4

让我们假设我们正在生成非常大的(例如 128 或 256 位)数字作为分组密码的密钥。

让我们进一步假设我们戴着锡纸帽子(至少在外面时)。

如此偏执,我们想确定我们可用的熵,但我们并不完全相信任何特定的来源。也许政府正在操纵我们的硬币。也许这些骰子的权重如此微妙。如果输入的硬件中断/dev/random有点过于一致怎么办?(除了偏执之外,我们很懒惰,不想手动生成它......)

所以,让我们把它们混合起来。

执行此操作的安全方法是什么?大概只是连接来自每个源的几个字节并不完全安全——如果其中一个源有偏差,理论上它可能会导致诸如相关密钥攻击之类的事情。

在连接的字节上运行 SHA-256 是否足够?

(是的,很快我会拿到一份 Cryptography Engineering 的副本。:))

4

4 回答 4

5

既然你提到/dev/random- 至少在 Linux 上,/dev/random由一种算法提供,该算法非常符合您的描述。它需要几个不同信任的熵源,并使用多项式函数将它们混合成一个“熵池”——对于进入的每个新的熵字节,它被异或到池中,然后整个池被搅拌混合功能。当需要从池​​中获得一些随机性时,整个池用 SHA-1 散列以获得输出,然后池再次混合(实际上还有更多的散列、折叠和破坏以确保逆转这个过程与逆转 SHA-1 一样难)。同时,还有大量的会计处理——每次将一些熵添加到池中时,都会将其价值的熵比特数的估计值添加到帐户中,并且每次从池中提取一些字节时,都会减去该数字,如果帐户低于零,随机设备将阻塞(等待更多的外部熵)。当然,如果您使用“urandom”设备,则不会发生阻塞,并且池只会不断进行散列和混合以产生更多字节,这会将其变成 PRNG 而不是 RNG。

Anyway... it's actually pretty interesting and pretty well commented -- you might want to study it. drivers/char/random.c in the linux-2.6 tree.

于 2010-08-07T10:31:43.497 回答
4

我以前做过这个,我的方法只是将它们逐个字节地相互异或。

通过其他算法(如 SHA-256)运行它们效率非常低,因此不实用,而且我认为它不会真正有用并且可能有害。

如果您确实非常偏执,并且有一点点钱,那么购买一个“真实的”(取决于您对 Quantum Mechanics 的确信程度)一个Quantum Random Number Generator可能会很有趣。

- 编辑:

FWIW,我认为我上面描述的方法(或类似的方法)从任一来源的角度来看实际上是一次性垫,假设其中一个是随机的,因此假设它们是独立的并且可以得到你。如果有人对此提出异议,我很高兴得到纠正,我鼓励任何不对此提出异议的人无论如何都要质疑它,并自己找出答案。

于 2010-08-07T07:13:29.877 回答
4

使用散列函数是一个好方法——只要确保你低估了每个源贡献的熵量,这样如果你对其中一个或多个不完全随机的情况是正确的,你就没有过度削弱你的密钥。

这与键拉伸中使用的方法没有什么不同(尽管您不需要在这里进行多次迭代)。

于 2010-08-07T10:00:09.040 回答
1

如果您有随机性来源,但不确定它是否有偏见,那么有很多不同的算法。根据您想要做的工作量,您从原始来源浪费的熵会有所不同。

最简单的算法是(改进的)范诺依曼算法。您可以在此 pdf 中找到详细信息: http ://security1.win.tue.nl/~bskoric/physsec/files/PhysSec_LectureNotes.pdf 第 27 页。

如果您对如何从给定的源中产生均匀随机性、真正的随机数生成器的工作原理等感兴趣,我还建议您阅读此文档!

于 2010-08-07T10:09:06.667 回答