我到处搜寻,找不到答案。我注意到我可以使用blake2b
库或hashlib
库,使用hmac
所指示的digestmod
库,hashlib
算法来生成消息摘要。所以:
plainMsg = "this is a plaintext message"
hashlib_hashed = hashlib.blake2b(key=b'super secret key')
hashlib_hashed.update(plainMsg.encode())
hmac_hashed = hmac.new(b'super secret key', digestmod=hashlib.blake2b)
hmac_hashed.update(plainMsg.encode())
print(hashlib_hashed.hexdigest())
print(hmac_hashed.hexdigest())
在我看来,他们应该使用相同的算法,相同的密钥和相同的纯文本生成与我相同的消息摘要。但是它们生成两个不同的摘要:
ec0d0ab13d7e7f3b62d742aa92078a4a14346ee6ee352e27c8814e4bf6361556fdc3d301e100b5a2c90c5596c4b2bb72c887c6b6aa92fb41752f6b52105ce13b
b632045e745550e5b9da6d411c013c978cb8120847260eb8fda9c8885368a5eaba80cd74ad95a51b1a4bde1f47cccb5a2e4591e9935126f673479c7474c2be97
我起初虽然与盐有关,但我没有将hashlib.blake2b()
与盐一起使用,所以我猜它自salt=b''
起就已经空了。但是使用hmac
却找不到如何设置盐的方法。那么,有人可以解释吗?
答案 0 :(得分:1)
HMAC算法不仅仅是“哈希密钥后跟消息”;填充密钥以匹配算法的块大小,然后将每个字节与固定的“ ipad”(0x36)进行异或,从该值计算哈希值,然后计算文本。然后,将原始的填充键与固定的“ opad”(0x5C)进行异或,然后再次从该新值计算哈希值,然后是上一步中的哈希值。
要点是,它没有您想像的那么直接。您可以查看the hmac.HMAC
class的内容,以了解Python遵循HMAC RFC的附加功能。
答案 1 :(得分:0)
您正在使用两种不同的算法来创建Message Authentication Code或MAC。
使用hmac
模块时,将创建散列的 MAC或HMAC。此处,密钥使用了两次(每次使用不同的XOR掩码)以在数据前添加值,并且使用哈希函数(由hashlib
库提供)在一个块处处理输入数据。在两个步骤中,首先需要将数据“压缩”为内部值,然后是第二个键之前的“外部”值。这使得该算法非常灵活,因为任何块哈希都可以适用于该技术。
带有密钥的BLAKE2也可以用于创建MAC,但是哈希函数 itself 然后使用该密钥生成“秘密”哈希输出,该哈希输出只能可以使用相同的密钥进行验证,因此也可以产生安全的签名。通过将密钥作为迭代哈希操作的第一个块来实现此目的。
但是Blake2 没有键只是另一个哈希函数,例如SHA256和其他函数,当您在HMAC中使用它时,不同的方法将产生不同的结果。两者不兼容,因为两种算法使用的密钥非常不同。
引用RFC 7693 – BLAKE2 Crypto Hash and MAC:
BLAKE2不需要 一种特殊的“ HMAC”(哈希消息验证码)构造 用于带密钥的消息身份验证,因为它具有内置的密钥 机制。
,并来自BLAKE2 section of the hashlib
documentation:
BLAKE2支持键控模式(一种更快更简单的HMAC替代),[...]
salt
函数的hashlib.blake2b()
参数是BLAKE2哈希算法的另一个功能,否则,您只需将盐加上哈希明文即可。盐会“随机化”输出,因此几乎不可能两次为同一输入消息产生相同的输出(从而使第三者无法检测到重复的消息)。