实际上,冲突比您在 MD5 和 SHA-1 上列出的更容易。MD5 冲突可以在相当于2 次26.5操作的时间内找到(其中一个“操作”是通过短消息计算 MD5)。有关攻击的一些详细信息和实现,请参阅此页面(我编写了该代码;它在 64 位模式下的 2.4 GHz Core2 x86 上平均 14 秒内发现冲突)。
同样,对 SHA-1 最著名的攻击是在大约2 61次操作中,而不是2 69次。它仍然是理论上的(尚未产生实际的碰撞),但它在可行的范围内。
至于对安全性的影响:散列函数通常被认为具有三个属性:
- 无原像:给定y ,找到x使得h(x) = y应该是不可行的。
- 没有第二个原像:给定x 1 ,找到x 2(与x 1不同)使得h(x 1 ) = h(x 2 )应该是不可行的。
- 没有冲突:找到任何x 1和x 2(彼此不同)使得h(x 1 ) = h(x 2 )应该是不可行的。
对于具有n位输出的散列函数,第一个属性的2 n次操作和第三个属性的2 n/2次操作中存在通用攻击(无论散列函数的细节如何都有效)。如果对于给定的散列函数,发现攻击,通过利用散列函数如何操作的特殊细节,比相应的通用攻击更快地找到原像、第二个原像或碰撞,那么散列函数被称为被“打破”。
但是,并非所有哈希函数的使用都依赖于所有三个属性。例如,数字签名首先对要签名的数据进行哈希处理,然后在算法的其余部分使用哈希值。这依赖于对原像和第二原像的抵抗力,但数字签名本身不受碰撞的影响。在某些特定的签名场景中,冲突可能是一个问题,其中攻击者可以选择要由受害者签名的数据(基本上,攻击者计算冲突,让受害者签署一条消息,并且签名对另一条消息)。这可以通过在计算签名之前在签名消息中添加一些随机字节来抵消(攻击和解决方案在 X.509 证书的上下文中演示)。
HMAC 安全性依赖于散列函数必须满足的另一个属性;即,“压缩函数”(构建散列函数的基本块)充当伪随机函数(PRF)。PRF 是什么的细节是相当技术性的,但粗略地说,PRF 应该与Random Oracle没有区别. 随机预言机被建模为一个黑匣子,其中包含一个侏儒、一些骰子和一本大书。在一些输入数据上,gnome 选择一个随机输出(用骰子)并在书中写下输入消息和随机选择的输出。gnome 使用这本书检查他是否已经看到相同的输入消息:如果是,则 gnome 返回与以前相同的输出。通过构造,在您尝试之前,您对给定消息的随机预言机的输出一无所知。
随机预言机模型允许在 PRF 的调用中量化 HMAC 安全证明。基本上,证据表明,如果不多次调用 PRF,就无法破坏 HMAC,而“巨大”是指计算上不可行的。
不幸的是,我们没有随机预言机,所以在实践中我们必须使用哈希函数。没有证据证明散列函数确实存在,具有 PRF 属性;现在,我们只有候选函数,即我们无法证明(还)它们的压缩函数不是 PRF 的函数。
如果压缩函数是 PRF ,那么哈希函数会自动抵抗冲突。这就是 PRF 的魅力所在。因此,如果我们可以找到哈希函数的冲突,那么我们就知道内部压缩函数不是 PRF。这不会将冲突转变为对 HMAC 的攻击。能够随意产生冲突无助于破坏 HMAC。但是,这些冲突表明与 HMAC 相关的安全证明不适用。保证无效。这与笔记本电脑一样:打开机箱不一定会损坏机器,但之后您就得靠自己了。
在Kim-Biryukov-Preneel-Hong文章中,介绍了对 HMAC 的一些攻击,特别是对 HMAC-MD4 的伪造攻击。该攻击利用了 MD4 的缺点(它的“弱点”),使其成为非 PRF。具有相同弱点的变体被用于在 MD4 上产生冲突(MD4 被彻底破坏;一些攻击产生的冲突比哈希函数本身的计算更快!)。因此,冲突并不意味着 HMAC 攻击,但两种攻击都以相同的源为食。但是请注意,伪造攻击的成本是2 58,这是相当高的(没有产生实际的伪造,结果仍然是理论上的)但大大低于 HMAC 预期的阻力水平(具有强大的散列函数和n- 位输出,HMAC 应抵抗高达2 n的工作因数;对于 MD4,n = 128 )。
因此,虽然冲突本身并不意味着 HMAC 的弱点,但它们是坏消息。在实践中,碰撞对于很少的设置来说是一个问题。但是知道冲突是否会影响哈希函数的给定用法已经够棘手的了,继续使用已经证明有冲突的哈希函数是非常不明智的。
对于 SHA-1,攻击仍然是理论上的,SHA-1 被广泛部署。情况是这样描述的:“警报响了,但没有可见的火灾或烟雾。是时候向出口走去——但不要逃跑。”
有关该主题的更多信息,请先阅读Menezes、van Oorschot 和 Vanstone 所著的《应用密码学手册》的第 9 章,这是密码学学徒的必读之书(不要与 B. Schneier 的“应用密码学”相混淆) ,这是一个写得很好的介绍,但没有“手册”那么透彻)。