这两种散列算法的安全性有什么不同吗?HMAC 是否以一种更安全的特殊方式“融合”数据和密钥?
HMAC-SHA256(key, data) 和 SHA256(key + data) 有什么区别
是的,HMAC 比简单的串联更复杂。
举个简单的例子,如果你只是简单地连接 key + data,那么 "key1"+"data" 会产生与 "key"+"1data" 相同的结果,这是次优的。HMAC 将为每个产生不同的结果。在许多情况下,简单连接也存在其他缺陷;请参阅cpast的答案之一。
HMAC 的规范称为RFC2104,如果您对此感兴趣,应该阅读该规范。
总之,要实现 HMAC,首先应该:
创建“ipad”,0x36
重复 BLOCKSIZE 次。创建“opad”,0x5c
重复 BLOCKSIZE 次。
- 请注意,根据RFC2104和RFC4868,对于 MD5、SHA-1、SHA-224、SHA-256,BLOCKSIZE 为 64 字节,对于 SHA-384 和 SHA-512 为 128 字节。
那么HMAC定义为:
HASH(Key XOR opad, HASH(Key XOR ipad, text))
或者,详细来自 RFC,
(借口:HMAC 的定义需要一个加密散列函数,我们用 H 表示,以及一个密钥 K。我们假设 H 是一个加密散列函数,其中数据通过在数据块上迭代基本压缩函数来散列。我们用 B 表示这些块的字节长度。)
(1) append zeros to the end of K to create a B byte string
(e.g., if K is of length 20 bytes and B=64, then K will be
appended with 44 zero bytes 0x00)
(2) XOR (bitwise exclusive-OR) the B byte string computed in step
(1) with ipad
(3) append the stream of data 'text' to the B byte string resulting
from step (2)
(4) apply H to the stream generated in step (3)
(5) XOR (bitwise exclusive-OR) the B byte string computed in
step (1) with opad
(6) append the H result from step (4) to the B byte string
resulting from step (5)
(7) apply H to the stream generated in step (6) and output
the result
实际上存在一个非常大的问题SHA256(key||data)
:SHA-256 以及 SHA-512、SHA-1、MD5 和所有其他使用 Merkle-Damgård 构造的哈希值都容易受到长度扩展攻击:给定H(x)
,很容易找到H(x||y)
,即使您只知道 的长度x
,因为构造是如何工作的。
(本质上,构造是这样工作的:您有一个变量state
,该变量从算法中指定的某个固定值开始。您将哈希函数的输入拆分为算法中指定大小的块(如果它太短,则填充最后一个块) ,对于每个块,你使用当前块和当前块使用算法中指定的一些特殊函数state
来计算新块。处理最后一个块后的值是哈希值。对于任何使用这种结构的函数,如果你有的长度,您可以计算使用的填充。然后,如果有,则处理完每个块后的状态,这意味着您可以从那里继续计算)。state
state
x
p
H(x)
x||p
H(x||p||y)
这意味着知道您的 MAC 密钥长度并知道特定值的攻击者SHA256(key||data)
可以轻松计算SHA256(key||data||otherdata)
一些给定的otherdata
. 他们可以选择大多数其他数据,但即使他们不能,如果没有密钥的攻击者可以从其他合法的 MAC 数据对伪造任何MAC 数据对,这也是 MAC 方案中的一个致命缺陷。
顺便说一句,SHA256(data||key)
虽然不易受到长度扩展的影响,但容易受到 中的冲突SHA256
,由于相同的迭代构造,这也可能在建议的 MAC 中产生冲突。HMAC 的嵌套可以防止这些和其他各种攻击。但是,对于非 Merkle-Damgård 哈希,您不一定需要 HMAC 构造。