我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛
密码概述
加密在日常生活中挺常见的,比如说你登陆网站,注册一个密码,密码到后端数据库入库就会进行加密。最常见的还有设置MySQL用户时,它的用户密码是会进行加密的,分为mysql_native_password和caching_sha2_password。
mysql_native_password其实就是SHA1,它是单向HASH算法,加密之后无法直接还原密码,曾经是比较安全的加密方式,但彩虹表技术的出现,让SHA1破解变得简单起来。
如果忘记了数据库的用户密码,且你的加密方式为mysql_native_password,不用着急,可以通过在线网站进行解密,就像这些:
你也可以直接修改相关密码。
caching_sha2_password如同它的名字,使用了SHA2哈希机制,现在基本上是不可被破解的。有兴趣的小伙伴们可以去详细研究。
当然以上都不是本文的重点,只是为了引出我们的主角,一个小众的高速流密码——Rabbit.
Rabbit兔子密码
Rabbit使用一个128位密钥和一个64位初始化向量。该加密算法的核心组件是一个位流生成器,该生成器每次迭代都会加密128个消息位。加密后的数据以U2FsdGVkX1开头,可以设定密钥。
流密码是一种对称加密算法,它的基本思想是使用密钥生成一个伪随机密钥流,再通过该密钥流进行加/解密。
给定一个64位字符串,函数MSW提取最高有效32位,函数LSW取最低有效32位。以0x为前缀的常量采用十六进制表示法。特别是,常量WORDSIZE被定义为0x100000000。
Rabbit 算法的核心是next-state状态函数,
square(u+v) = ((u+v mod WORDSIZE) * (u+v mod WORDSIZE)
g(u,v) = LSW(square(u+v)) ^ MSW(square(u+v))
for j=0 to 7:
Gj = g(Xj,Cj)
X0 = G0 + (G7 <<< 16) + (G6 <<< 16) mod WORDSIZE
X1 = G1 + (G0 <<< 8) + G7 mod WORDSIZE
X2 = G2 + (G1 <<< 16) + (G0 <<< 16) mod WORDSIZE
X3 = G3 + (G2 <<< 8) + G1 mod WORDSIZE
X4 = G4 + (G3 <<< 16) + (G2 <<< 16) mod WORDSIZE
X5 = G5 + (G4 <<< 8) + G3 mod WORDSIZE
X6 = G6 + (G5 <<< 16) + (G4 <<< 16) mod WORDSIZE
X7 = G7 + (G6 <<< 8) + G5 mod WORDSIZE
更多详细内容请看 RFC 4503: A Description of the Rabbit Stream Cipher Algorithm (rfc-editor.org).
Java代码实现:
private void next_state()
{
int[] g = new int[8];
int[] c_old = new int[8];
int i;
for( i = 0; i < 8; i++)
{
c_old[i] = c[i];
}
c[0] += 0x4d34d34d + carry;
c[1] += 0xd34d34d3 + compare(c[0], c_old[0]);
c[2] += 0x34d34d34 + compare(c[1], c_old[1]);
c[3] += 0x4d34d34d + compare(c[2], c_old[2]);
c[4] += 0xd34d34d3 + compare(c[3], c_old[3]);
c[5] += 0x34d34d34 + compare(c[4], c_old[4]);
c[6] += 0x4d34d34d + compare(c[5], c_old[5]);
c[7] += 0xd34d34d3 + compare(c[6], c_old[6]);
carry = compare(c[7], c_old[7]);
for( i = 0; i < 8; i++)
{
g[i] = g_func(x[i] + c[i]);
}
x[0] = g[0] + rotL(g[7], 16) + rotL(g[6], 16);
x[1] = g[1] + rotL(g[0], 8 ) + g[7];
x[2] = g[2] + rotL(g[1], 16) + rotL(g[0], 16);
x[3] = g[3] + rotL(g[2], 8 ) + g[1];
x[4] = g[4] + rotL(g[3], 16) + rotL(g[2], 16);
x[5] = g[5] + rotL(g[4], 8 ) + g[3];
x[6] = g[6] + rotL(g[5], 16) + rotL(g[4], 16);
x[7] = g[7] + rotL(g[6], 8 ) + g[5];
}
因为兔子密码当时是设计用来大量数据加密的,并且MD5、DES等早已被投入使用,所以造成了它的使用并不多,知道的人也很少。
但现在我们也可以对其算法思想进行一定学习,说不定就能创新出另一个兔子加密算法呢?
一个小解密游戏,这是个盲兔子,竟然在唱歌! - Bugku CTF
附件为:
⡥⠂⡶⡃⡔⡷⡦⡛⡨⠁⠟⡚⠉⠇⡳⡜⡉⡤⡴⡑⡓⡆⡑⡔⡆⡠⡩⡹⠂⡢⡪⡵⡢⡟⡶⡹⠃⡒⠁⡥⡞⠟⡚⡞⡣⡣⡤⡀⡡⡆⠉⡼⡻⠀⠉⡧⡙⠇⡦⡇⡧⡅⡺⡑⠺⡑⡉⡑⠂⡞⡱⡳⠁⡊⡢⡩⡊⡚⡊⡕⡛⠀⡕⠂⡩⡱⡾⡴⠂⡶⡛⠈⡹⡇⡗⡑⠃⠁⡆⡝⡽⡺⡨⡙⠛⠅⠁⡠⡇⡩⡅⡸⡑⡧⡑⡸⠅⡆⡨⠛⡣⡨⡑⡢⡝⠁⡟⡚⡿⠺⠛⡿⡕⡴⡛⡡⠀⡔⠉⠂⡴⡃⠃⠀⡿⡹⠄⡺⡀⡵⡊⡝⡪⡨⡛⡦⡖⡛⡧⡡⡪⠈⡲⠟⡝⡔⡕⠅⡄⡞⠟⠂⡵⡉⠅⡩⡦⡼⡈⡴⡩⡈⠟⡞⡦⡩⡆⡛⡴⡾⡈⡁⡁⡗⠺⡹⡾⡆⡢⡹⡠⡈⡃⡛⠆⡁⡖⡻⡉⡡⡻⡓⠆⡁⡼⡷⠃⡛⠅⡵⠈⡝⡂⠉⡃⡄⡠⡠⡡⡒⡁⡃⡁⠅⡾⡨⠆⡘⠇⡄⡁⡲⠅⡖⠛⡓⡤⡃⡕⡺⡃⡝⡛⡳⠀⡢⡒⡙⠂⠺⡱⡉⡻⡒⡨⡄⡒⡒⡈⡱⡧⡽⠆⡉⡷⡹⠛⡊⠟⡥⡜⡳⡶⠆⡺⠉⠂⡂⡛⡥⡓⡝⡴⠆⡽⡟⠅⡿⡻⡸⡺⠆⡇⠂⠈⡼⡤⡕⠂⠈⡤⠅⠛⠁⡇⡟⡧⡈⡗⡲⡊⡸⠉⡻⠺⡱⡻⡥⠍=其中就运用到了盲文、rabbit、音乐符号。