我不知道有任何关于 MySQL 的已发表密码分析OLD_PASSWORD(),但它太弱了,简直是个笑话。它可以作为密码学课程中的练习。
更新: 类似于下面描述的中间相遇的密码分析发表在2006 年国际信息安全和密码学会议 - ICISC 2006上的F. Muller 和 T. Peyrin “基于 T 函数的散列函数的密码分析”,具有更通用的描述,并进行了一些优化以查找短密码并保存在 RAM 中。
例如,这是一个“恢复”内部状态的 C 代码:
static int
oldpw_rev(uint32_t *pnr, uint32_t *pnr2, uint32_t add,
        unsigned char *cc, unsigned len)
{
        uint32_t nr, nr2;
        uint32_t c, u, e, y;
        if (len == 0) {
                return 0;
        }
        nr = *pnr;
        nr2 = *pnr2;
        c = cc[len - 1];
        add -= c;
        u = nr2 - nr;
        u = nr2 - ((u << 8) ^ nr);
        u = nr2 - ((u << 8) ^ nr);
        nr2 = nr2 - ((u << 8) ^ nr);
        nr2 &= 0x7FFFFFFF;
        y = nr;
        for (e = 0; e < 64; e ++) {
                uint32_t z, g;
                z = (e + add) * c;
                g = (e ^ z) & 0x3F;
                if (g == (y & 0x3F)) {
                        uint32_t x;
                        x = e;
                        x = y ^ (z + (x << 8));
                        x = y ^ (z + (x << 8));
                        x = y ^ (z + (x << 8));
                        nr = y ^ (z + (x << 8));
                        nr &= 0x7FFFFFFF;
                        if (oldpw_rev(&nr, &nr2, add, cc, len - 1) == 0) {
                                *pnr = nr;
                                *pnr2 = nr2;
                                return 0;
                        }
                }
        }
        return -1;
}
当在数组len中给出的密码字符(和,两个 31 位字,以及密码字符之和的值)之后给出内部状态时,此函数计算插入密码之前和之前的有效解人物。这是有效的。cc[]nrnr2addnrnr2 
这导致了一个简单的中间相遇攻击。考虑 14 个小写 ASCII 字母的序列,这样每个字母后面跟着它的补码('a' 的补码是 'z','b' 的补码是 'y',等等......)。大约有 80 亿个这样的序列。请注意,任何这些序列的字符总和始终是固定值 1533。取其中N个序列;对于它们中的每一个,用 计算相应的哈希OLD_PASSWORD()值,并将值累积到一个大文件中:每个条目包含字符序列,以及对应的nrand nr2。然后按 62 位nr/nr2对对文件进行排序。这个文件是一个大表:“使用这个序列,我们从初始值到那个 内部状态”。
然后再次获取N个序列,这次使用oldpw_rev()(如上所示)对它们中的每一个,使用实际被攻击的散列作为起点,对于nr和nr22*1533 == 3066 add。这将为您提供N其他对nr/ nr2,每对都有相应的序列。这些值累积在另一个文件中,您再次按 62 位nr/nr2对排序。第二个文件是一个大表:“在那个内部状态上使用这个序列,我们获得了我们当前正在攻击的哈希值”。
此时您只需找到两个匹配的对,即第一个文件和第二个文件中的相同nr/ nr2。相应的 14 个字符序列是与哈希输出匹配的 28 个字符密码的两半。这可能不是最初使用的密码,但这是一个将哈希到相同值并被 MySQL 接受的密码。当N达到 20 亿左右时,您获得匹配对的可能性很高(我们在大小为2 62的空间中,因此N大约为sqrt(2 62 )就足够了)。
这种攻击的工作因数约为2 37(考虑到排序步骤),远小于理论上可以使用具有 62 位输出的哈希函数实现的2 62工作因数(对于适当的安全性来说,这已经太低了) )。因此,该OLD_PASSWORD()功能被密码破解。
(可能有比这更好的攻击。)