让我们假设我们生成非常大的(例如128或256位)数字作为分组密码的密钥。
让我们进一步假设我们戴着锡箔帽(至少在外面时)。
如此偏执,我们希望确定我们的可用熵,但我们并不完全信任任何特定的来源。也许政府正在操纵我们的硬币。也许这些骰子是如此微妙的加权。如果硬件中断馈入/dev/random
只是一点太一致怎么办? (除了偏执,我们很懒,我们不想手工制作它们......)
所以,让我们把它们混合起来。
这样做的安全方法是什么?据推测,只是从每个源连接几个字节并不完全安全 - 如果其中一个源有偏差,理论上它可能适用于诸如相关密钥攻击之类的东西。
在连续的字节上运行SHA-256是否足够?
(是的,很快我会在很短的时间内拿到一份密码工程。:))
答案 0 :(得分:5)
自从你提到/dev/random
- 至少在Linux上,/dev/random
由一个算法提供,这个算法非常符合你的描述。它需要几个不同信任的熵源,并使用多项式函数将它们混合到一个“熵池”中 - 对于每个新的熵字节进入,它被放入池中,然后整个池被搅动混合功能。当希望从池中获得一些随机性时,整个池用SHA-1进行哈希处理以获得输出,然后池再次混合(实际上还有一些哈希,折叠和残留,以确保扭转过程与扭转SHA-1一样困难。与此同时,还有一堆会计正在进行 - 每次将一些熵添加到池中时,会将其值的熵值的估计值添加到帐户中,并且每次从一些字节中提取一些字节。池,该数字被减去,如果账户低于零,随机设备将阻止(等待更多的外部熵)。当然,如果你使用“urandom”设备,阻塞不会发生,并且池只是不断地进行散列和混合以产生更多的字节,从而将其转换为PRNG而不是RNG。
无论如何......它实际上非常有趣且评论很好 - 您可能想要研究它。 drivers/char/random.c
树中的linux-2.6
。
答案 1 :(得分:4)
使用哈希函数是一种很好的方法 - 只要确保你低估每个来源贡献的熵量,这样如果你对其中一个或多个不完全随机的正确,你就没有削弱你的密钥过度。
这与key stretching中使用的方法没有什么不同(虽然这里不需要多次迭代)。
答案 2 :(得分:3)
我以前做过这个,而我的方法只是逐字逐句地对它们进行异或。
运行它们通过其他一些算法,比如SHA-256,非常低效,所以它不实用,而且我认为它不会真正有用而且可能有害。
如果你确实遇到了令人难以置信的偏执,并且只需要一点点钱,那么购买“真实”(取决于您对量子力学的信任程度)a Quantum Random Number Generator可能会很有趣。
- 编辑:
FWIW,我认为上面描述的方法(或类似的东西)从任何一个来源的角度来看实际上都是One-Time Pad,假设其中一个是随机的,因此假设它们是独立的并且是不可见的要得到你。如果有人对此提出异议,我很高兴能够对此予以纠正,我鼓励任何不对其提出质疑的人提出质疑,并亲自了解。
答案 3 :(得分:1)
如果你有一个随机源,但你不确定它是否有偏差,那么有很多不同的算法。根据您想要做多少工作,您从原始资源中消耗的熵不同。
最简单的算法是(改进的)van Neumann算法。您可以在此pdf中找到详细信息: http://security1.win.tue.nl/~bskoric/physsec/files/PhysSec_LectureNotes.pdf 在第27页。
如果您对如何从给定的源产生均匀的随机性,真正的随机数生成器如何工作等感兴趣,我还建议您阅读本文档。