高速流密码——Rabbit

2,568 阅读2分钟

我正在参加「兔了个兔」创意投稿大赛,详情请看:「兔了个兔」创意投稿大赛

密码概述

加密在日常生活中挺常见的,比如说你登陆网站,注册一个密码,密码到后端数据库入库就会进行加密。最常见的还有设置MySQL用户时,它的用户密码是会进行加密的,分为mysql_native_password和caching_sha2_password。

mysql_native_password其实就是SHA1,它是单向HASH算法,加密之后无法直接还原密码,曾经是比较安全的加密方式,但彩虹表技术的出现,让SHA1破解变得简单起来。

如果忘记了数据库的用户密码,且你的加密方式为mysql_native_password,不用着急,可以通过在线网站进行解密,就像这些:

MD5免费在线解密破解_MD5在线加密-SOMD5

md5在线加密解密

你也可以直接修改相关密码。

解密示例.png

caching_sha2_password如同它的名字,使用了SHA2哈希机制,现在基本上是不可被破解的。有兴趣的小伙伴们可以去详细研究。

当然以上都不是本文的重点,只是为了引出我们的主角,一个小众的高速流密码——Rabbit.

Rabbit兔子密码

Rabbit使用一个128位密钥和一个64位初始化向量。该加密算法的核心组件是一个位流生成器,该生成器每次迭代都会加密128个消息位。加密后的数据以U2FsdGVkX1开头,可以设定密钥。

rabbit.png

流密码是一种对称加密算法,它的基本思想是使用密钥生成一个伪随机密钥流,再通过该密钥流进行加/解密。

给定一个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、音乐符号。

在线Rabbit加密 | Rabbit解密- 在线工具 (sojson.com)