碰撞攻击对密码散列没有影响,尽管可能有一些细节取决于你散列的目的。粗略地说,当我们散列密码时,我们可能想做两件事:
密码验证仅适用于对原像的抵抗(找到一个值m以使h(m)匹配给定输出的难度)。但是,密钥派生需要的远不止这些。理想情况下,对于密钥派生,散列函数的行为应该尽可能接近神话中的随机预言。我们已经知道基于Merkle-Damgård 构造的哈希函数,例如 MD5 或 SHA-256,不是随机预言机(因为“长度扩展攻击”);然而,我们可以在HMAC中使用这样的函数,它使用两个嵌套的哈希函数调用来精确地避免 MD 构造问题。但HMAC 仅相对于哈希函数的内部属性(即内部“压缩函数”应该与 PRF 无法区分)被“证明”安全,并且我们知道在 MD5 的情况下不满足此属性,因为否则会发生冲突攻击是不可行的……
综上所述,在使用 MD5 进行密钥派生时,我们需要应用HMAC-DRBG(一种基于重复 HMAC 调用的 PRNG)等方案,内部使用 MD5。众所周知,只要散列函数很强,这种方案就很强大,虽然碰撞攻击不直接适用,但它们表明这种“强度”没有实现。因此,担保无效。目前没有人知道如何削弱 HMAC/MD5,但我们有 MD4 的例子:MD4 被彻底破坏以防碰撞(碰撞可以“立即”产生),并且有一个已知的对 HMAC/MD4 的攻击,这是相当昂贵但仍然比理论上的 2 128快得多. 对 HMAC/MD4 的攻击不利用冲突,而是建立在与设计冲突攻击的同一来源的不同路径上。因此,高度怀疑HMAC/MD5 不如 HMAC/SHA-256 强(即使截断为 128 位)。
相应地,对于密钥派生,不要使用 MD5。它不会立即被打破,但它仍然在寻找麻烦。无需立即迁移使用 MD5 进行密码散列的现有系统,但对于新设计,您应该避免使用它。
强制提醒:
当然,在对密码进行哈希处理时,无论预期用途如何(密码验证或密钥派生),您都应应用盐和可配置的慢速。由于管理密码的人脑的生物学限制,密码本身就是一个弱点。盐和可配置的缓慢是应对它的方法:盐阻碍并行性(攻击者无法在多个密码实例之间共享攻击成本——例如通过彩虹表等预先计算的表),而缓慢则违背摩尔定律(计算机随着时间的推移变得更快,但人类大脑没有)。因此,您不想使用“仅 MD5”对密码进行散列,而是使用专用的密码散列函数,例如PBKDF2或bcrypt。PBKDF2 内部使用散列函数,例如 MD5。碰巧 MD5(如 SHA-256)很好地映射了GPU的计算能力,这使得它成为这项工作的一个值得商榷的选择,而 bcrypt 可以说更好(有关详细信息,请参阅此答案)。