通过散列一个 N 位随机密钥来产生一个 N 位散列是否会丢失熵?

信息安全 哈希 随机的
2021-08-12 02:40:55

我阅读了以下代码:

dd if=/dev/urandom bs=16 count=1 2>/dev/null | md5sum

显然,此代码被用作从 128 位二进制伪随机值生成十六进制字符串密钥的技巧。

这里有人声称这本质上是不安全的,因为它通过“不安全的哈希函数”传递加密安全的随机值。

就我而言,我想说 md5 中的碰撞缺陷在这里无关紧要,因为散列函数输入和输出具有相同的大小。因此,哈希函数的输出与其输入一样随机。

你对此有何看法?对 N 位随机密钥进行散列以产生 N 位散列会改变密钥的随机性吗?

2个回答

散列是一个确定性的过程,这意味着它永远不会增加随机性。但是当然它可以降低随机性:如果你用一些只输出 160 位的散列算法(如 SHA-1)散列一个 200 位的随机值,那么结果值当然永远不会有 200 位的随机性。

但只要输入位数显着低于散列的输出大小,它就不会降低随机性,只要使用加密散列即可。如果输入大小与您的示例中的输入大小完全相同,则使用加密哈希时产生的随机性可能不会显着降低。你是对的,碰撞阻力对此无关紧要。

dd if=/dev/urandom bs=16 count=1 2>/dev/null | md5sum

这保证会损失一些熵,但不会太多。攻击MD5的难度并不能直接说明损失的大小,而只是告诉我们它不为零。

如果我回到朴素的构造,我发现熵损失可以从63.21% 的不动点概率中计算出来。这反过来意味着丢失了不到一位的熵。我忘记了你实际需要多少,但我知道 122 位的真实熵就足够了。

另一方面,你想在这里完成什么?dd if=/dev/urandom bs=16 count=1本身就足够了。尝试使用 md5 来防御kekkak-f的弱点是没有意义的。

如果您真的觉得需要在这里做点什么,请制作一个 128 位应用程序密钥,在安装时直接从/dev/random(not urandom) 生成它,然后将其异或到来自/dev/urandom. 但我看不出有什么理由可以举起手指来做这件事。