我四处搜索,却找不到答案。我注意到我可以使用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
我没有找到如何设置盐。那么,谁能解释一下?
HMAC算法不仅仅是“散列密钥后跟消息”;填充该键以匹配算法的块大小,然后将每个字节与固定的“ipad”(0x36)进行异或,从该值计算散列,然后计算文本。然后原始填充密钥与固定的“opad”(0x5C)进行异或,并再次从该新值计算哈希值,然后是上一步骤的哈希值。
重点是,它并不像你想象的那么简单。您可以查看the hmac.HMAC
class的内容,以查看Python遵循HMAC RFC所做的额外操作。
您正在使用两种不同的算法来创建Message Authentication Code或MAC。
当您使用hmac
模块时,您将创建一个散列MAC或HMAC。这里,密钥使用两次(每次使用不同的XOR掩码)为数据前置一个值,并使用哈希函数(由hashlib
库提供)一次处理一个块的输入数据以'压缩'数据首先进入内部值,然后是在第二个键之前的外部值,分为两步。这使得算法非常灵活,因为任何块散列都可以适用于该技术。
带有密钥的BLAKE2也可用于创建MAC,但是哈希函数本身然后使用该密钥生成“秘密”哈希输出,只能使用相同的密钥进行验证,因此产生安全签名也是。它通过使密钥成为迭代散列操作的第一个块来实现。
但是没有键的Blake2只是另一个哈希函数,比如SHA256和其他哈希函数,当你在HMAC中使用它时,不同的方法会产生不同的结果。两者不兼容,因为这两种算法使用它们的密钥非常不同。
引自RFC 7693 – BLAKE2 Crypto Hash and MAC:
BLAKE2不需要特殊的“HMAC”(哈希消息认证码)构造用于键控消息认证,因为它具有内置的键控机制。
并从BLAKE2 section of the hashlib
documentation:
BLAKE2支持键控模式(更快更简单的HMAC替换),[...]
salt
函数的hashlib.blake2b()
参数是BLAKE2散列算法的一个不同特征,否则你只需要用散列明文前缀盐。 salt会使输出“随机化”,因此很可能两次为同一输入消息生成相同的输出(使第三方无法检测到重复的消息)。