如果$ H(m)$是一个安全的哈希函数,那么我们不能使用$ H(k \ mathbin \ Vert m)$来实现MAC吗?

但是,似乎使用更广泛的MAC ,例如NMAC和HMAC(两者均最初在用于消息认证的Keying哈希函数中定义)使用了更为复杂的方案。为什么这种串联方案不安全?

评论

另请参见en.wikipedia.org/wiki/Length_extension_attack

#1 楼

“安全散列函数”一词通常表示(对于函数$ H $)


原像抵抗:给定值$ h $,很难找到消息$ x $,因此$ h = H(x)$。
第二原像抵抗:给定一条消息$ x $,很难找到一条消息$ x'\ neq x $,使得$ H(x)= H(x ')$。
抗冲突性:很难找到两个消息$ x $,$ x'$,使得$ H(x)= H(x')$。

安全的MAC功能$ M $,我们想要:


不可伪造性:不知道密钥$ k $,很难找到消息$ x $和身份验证标签$ m $这样的$ m = M(k,x)$,即使给出了其他一些有效的消息标签对(不允许作为答案)也是如此。

不幸的是,定义了$ M(k,x) = H(k \ mathbin \ Vert x)$表示安全哈希函数不能保证MAC函数不可伪造。 MD5,SHA-1和SHA-2家族中使用的结构,没有完成最后一轮y),在给定有效对$(x,m)$的情况下,创建仍然有效的$(x',m')$是很容易的:

使用Merkle-Damgård,将消息填充到某个块大小,然后按顺序将每个块馈送到压缩功能,该功能会更新内部状态。然后将最终状态作为哈希输出。

因此,$ H(k \ mathbin \ Vert x)$是输入$ k \ mathbin \ Vert x \ mathbin \后哈希机的状态。 Vert \ mathit {pad} _x $。如果我们将哈希机设置为此状态,然后输入任意其他数据$ y $,然后输入另一个填充$ \ mathit {pad} _y $,则我们将达到状态$ m'= H(k \ mathbin \ Vert x \ mathbin \ Vert \ mathit {pad} _x \ mathbin \ Vert y)= M(k,x \ mathbin \ Vert \ mathit {pad} _x \ mathbin \ Vert y)$。
使用$ x进行伪造'= x \ mathbin \ Vert \ mathit {pad} _x \ mathbin \ Vert y $。

这也适用于SHA-2的全角变体,即SHA-256和SHA-512。对于SHA-2的截短变体(SHA-384,SHA-224,SHA-512 / 224和SHA-512 / 256),此攻击无效,因为输出不是完整的哈希状态。 (尽管对于长度扩展攻击,只需要猜测截断的位,因此安全性就比输出大小所期望的要低。)

HMAC结构对于这种攻击是不可怀疑的,因为秘密密钥$ k $在主消息之前和之后都应用,这使得内部状态不可重建。

HMAC也不保证常规安全哈希函数的不可伪造性,但是它具有如果内部压缩功能具有抗碰撞性,则可以为Merkle-Damgård构造提供安全性证明。

SHA-3(Keccak)基于不同的模型:我们处于一个相当大的状态,密钥和消息混合在一起,然后进一步混合以输出哈希。状态本身永远不会完全输出。因此,长度扩展需要状态恢复,并且容量(状态的隐藏部分)应足够大以至于不可行(以及猜测密钥)。
Keccak团队对键控海绵结构的安全性进行了分析。

评论


$ \ begingroup $
请注意,对于SHA-3(Keccak),现在定义了一种称为KMAC的算法,该算法基本上直接使用基于海绵的哈希。它使用略有不同的配置,因此它不会输出与散列相同的值,仅此而已。
$ \ endgroup $
–马腾·博德威斯♦
20 Apr 14 '18:17

#2 楼

$ H(k \ mathbin | m)$(其中$ | $是串联)不是标准的原因是来自消息扩展攻击。如果我作为攻击者拥有$ H(k \ mathbin | m)$和$ m $,我可以计算$ H(k \ mathbin | m \ mathbin | p \ mathbin | m')$(其中$ p $是$ H $在计算摘要时将应用于$ k \ mathbin | m $的填充,而$ m'$是任意消息)而又不知道$ k $。然后,我将向用户发送$ H(k \ mathbin | m \ mathbin | p \ mathbin | m')$和$ m \ mathbin | p \ mathbin | m'$。消息身份验证检查将成功。显然这是一个问题。

评论


$ \ begingroup $
这可能是一个愚蠢的问题,但是如何在不知道k的情况下计算H(k | m | p | m')?
$ \ endgroup $
– Mulllhausen
2015年3月22日在1:03



$ \ begingroup $
没关系。我找到了一个可行的示例github.com/iagox86/hash_extender
$ \ endgroup $
– Mulllhausen
15年3月22日在1:36

$ \ begingroup $
除了邮件扩展攻击(假设所有邮件都是固定大小)之外,还有问题吗?
$ \ endgroup $
–chux-恢复莫妮卡
17年2月3日在21:45

$ \ begingroup $
@chux,您应该将其作为一个单独的问题提出。
$ \ endgroup $
– Mikeikeazo
17年2月4日,下午3:35