关于/dev/urandom 的流言终结(3)
Linux 内核只使用事件的到达时间来预估熵的量。根据模型,它通过多项式插值来预估实际的到达时间有多“出乎意料”。这种多项式插值的方法到底是不是好的预估熵量的方法本身就是个问题。同时硬件情况会不会以某种特定的方式影响到达时间也是个问题。而所有硬件的取样率也是个问题,因为这基本上就直接决定了随机数到达时间的颗粒度。 说到最后,至少现在看来,内核的熵预估还是不错的。这也意味着它比较保守。有些人会具体地讨论它有多好,这都超出我的脑容量了。就算这样,如果你坚持不想在没有足够多的熵的情况下吐出随机数,那你看到这里可能还会有一丝紧张。我睡的就很香了,因为我不关心熵预估什么的。 最后要明确一下: Linux 4.8 以后image: actual structure of the kernel's random number generator from Linux 4.8 onward 在 Linux 4.8 里, 我们很快会理解为什么这不是一个安全问题。(参见:“CSPRNG 没问题”一节) 阻塞有什么问题?你有没有需要等着 这些都是问题。阻塞本质上会降低可用性。换而言之你的系统不干你让它干的事情。不用我说,这是不好的。要是它不干活你干嘛搭建它呢?
但其实有个更深刻的问题:人们不喜欢被打断。它们会找一些绕过的方法,把一些诡异的东西接在一起仅仅因为这样能用。一般人根本不知道什么密码学什么乱七八糟的,至少正常的人是这样吧。 为什么不禁止调用 到头来如果东西太难用的话,你的用户就会被迫开始做一些降低系统安全性的事情——你甚至不知道它们会做些什么。 我们很容易会忽视可用性之类的重要性。毕竟安全第一对吧?所以比起牺牲安全,不可用、难用、不方便都是次要的? 这种二元对立的想法是错的。阻塞不一定就安全了。正如我们看到的, CSPRNG 没问题现在情况听上去很惨淡。如果连高质量的 实际上,“看上去随机”是现存大多数密码学基础组件的基本要求。如果你观察一个密码学哈希的输出,它一定得和随机的字符串不可区分,密码学家才会认可这个算法。如果你生成一个分组加密,它的输出(在你不知道密钥的情况下)也必须和随机数据不可区分才行。 如果任何人能比暴力穷举要更有效地破解一个加密,比如它利用了某些 CSPRNG 伪随机的弱点,那这就又是老一套了:一切都废了,也别谈后面的了。分组加密、哈希,一切都是基于某个数学算法,比如 CSPRNG。所以别害怕,到头来都一样。 那熵池快空了的情况呢?毫无影响。 加密算法的根基建立在攻击者不能预测输出上,只要最一开始有足够的随机性(熵)就行了。“足够”的下限可以是 256 位,不需要更多了。 介于我们一直在很随意的使用“熵”这个概念,我用“位”来量化随机性希望读者不要太在意细节。像我们之前讨论的那样,内核的随机数生成器甚至没法精确地知道进入系统的熵的量。只有一个预估。而且这个预估的准确性到底怎么样也没人知道。 重新选种但如果熵这么不重要,为什么还要有新的熵一直被收进随机数生成器里呢?
首先,一般不会这样。如果你有很多随机性可以拿来用,用就对了! 但随机数生成器时不时要重新选种还有别的原因: 想象一下如果有个攻击者获取了你随机数生成器的所有内部状态。这是最坏的情况了,本质上你的一切都暴露给攻击者了。 你已经凉了,因为攻击者可以计算出所有未来会被输出的随机数了。 但是,如果不断有新的熵被混进系统,那内部状态会再一次变得随机起来。所以随机数生成器被设计成这样有些“自愈”能力。 但这是在给内部状态引入新的熵,这和阻塞输出没有任何关系。 random 和 urandom 的 man 页面这两个 man 页面在吓唬程序员方面很有建树:
没有“公开的文献”描述,但是 NSA 的小卖部里肯定卖这种攻击手段是吧?如果你真的真的很担心(你应该很担心),那就用 然而事实是,可能某个什么情报局有这种攻击,或者某个什么邪恶黑客组织找到了方法。但如果我们就直接假设这种攻击一定存在也是不合理的。 而且就算你想给自己一个安心,我要给你泼个冷水:AES、SHA-3 或者其它什么常见的加密算法也没有“公开文献记述”的攻击手段。难道你也不用这几个加密算法了?这显然是可笑的。 我们在回到 man 页面说:“使用 如果你真的需要信息论安全性的随机数(你不需要的,相信我),那才有可能成为唯一一个你需要等足够熵进入 CSPRNG 的理由。而且你也不能用 man 页面有毒,就这样。但至少它还稍稍挽回了一下自己:
|