如果我在 Ubuntu 中运行此命令
sudo cat /proc/sys/kernel/random/entropy_avail
它返回一个数字,表示内核可用的“熵”量,但我所知道的就这些了。这个熵的单位是什么?它有什么用?有人告诉我,如果这个数字“低”,那就是“坏”。“低”到底有多低?如果低,会发生什么“坏”事?熵的合理范围是多少?如何确定?
答案1
您的系统通过关注不同的事件来收集一些“真实”随机数:网络活动、硬件随机数生成器(如果可用;例如 VIA 处理器通常有一个“真实”随机数生成器)等等。如果将这些提供给内核熵池,则由 /dev/random 使用。需要极端安全性的应用程序倾向于使用 /dev/random 作为其熵源,换句话说,随机源。
如果 /dev/random 耗尽了可用的熵,它就无法提供更多的随机性,等待随机性的应用程序会停滞,直到有更多随机性可用。在我的职业生涯中,我见过的例子是 Cyrus IMAP 守护进程想要使用 /dev/random 来获得随机性,而它的 POP 会话想要从 /dev/random 生成 APOP 连接中的随机字符串。在繁忙的环境中,登录尝试次数多于为 /dev/random 提供信息的流量 -> 一切都停滞了。在这种情况下,我安装了 rng-tools 并激活了它拥有的 rngd - 如果 /dev/random 耗尽了“真实”熵,它会将半随机数从 /dev/urandom 铲到 /dev/random。
答案2
如果您想更简单地概述底层问题:某些应用程序(例如加密)需要随机数。您可以使用算法生成随机数 - 但尽管这些数字在某种意义上似乎是随机的,但在另一种意义上却是完全可预测的。例如,如果我给您数字 58209749445923078164062862089986280348253421170679,它们看起来非常随机。但如果您意识到它们实际上是 PI 的数字,那么您就会知道下一个将是 8。
对于某些应用程序来说,这是可以的,但对于其他应用程序(尤其是与安全相关的应用程序),人们想要的是真正的不可预测的随机性——这不能由算法(即程序)生成,因为从定义上讲,这是可预测的。这是一个问题,因为你的计算机本质上是程序如何才能获得真正的随机数?答案是通过测量来自外部世界的真正随机事件 - 例如按键之间的间隙,并利用这些事件将真正的随机性注入原本可预测的随机数生成器中。“熵池”可以被认为是这种随机性的存储,它由击键(或正在使用的任何内容)建立,并通过随机数的生成耗尽。
答案3
熵是“随机性”的技术术语。计算机实际上并不产生熵,而是通过观察硬盘转速变化(由于摩擦等原因,这种物理现象很难预测)等来收集熵。当计算机想要生成伪随机数据时,它会用通过测量鼠标点击、硬盘旋转变化等找到的真熵来植入数学公式。粗略地说,entropy_avail
熵是当前可读取的位数/dev/random
除非计算机具有像噪声二极管或类似物之类的酷硬件,否则计算机需要时间从其环境中读取熵。
如果有 4096 位可用熵,并且您使用 cat,那么/dev/random
您可以预期在文件阻塞并等待更多熵之前能够读取 512 字节的熵(4096 位)。
例如,如果你“ cat /dev/random
”,你的熵将缩小到零。一开始你会得到 512 字节的随机垃圾,但它会停止,一点一点地,你会看到更多的随机数据涓涓细流。
但这不是人们应该采取的操作方式/dev/random
。通常,开发人员会读取少量数据(例如 128 位),并用它来播种某种 PRNG 算法。出于礼貌,不要读取/dev/random
比您需要的更多的熵,因为需要很长时间才能积累起来,而且这些熵很有价值。因此,如果您cat
像上面一样粗心地将文件读空,您将导致需要读取的其他应用程序被/dev/random
阻止。在工作的一个系统上,我们注意到许多加密功能都停滞了。我们发现一个 cron 作业正在调用一个 python 脚本,该脚本ramdom.random()
在每次运行时都会不断初始化,而该脚本每隔几秒钟就会运行一次。为了解决这个问题,我们重写了 python 脚本,使其作为仅初始化一次的守护进程运行,并且 cron 作业将通过 XMLRPC 读取数据,这样它就不会在/dev/random
启动时继续读取。
答案4
这已经过时了,但其他答案并没有真正解决这个问题。熵是衡量选择过程产生随机值的能力的指标。熵被定义为值 S,这样最好的猜测攻击平均需要 S/2 次猜测。SE 上其他地方有很多关于这方面的内容(这里, 例如)。
熵通常以位为单位来衡量。例如,如果 S 为 256,则熵为 8 位,最佳攻击平均需要 128 次猜测。在现代 Linux 内核(5.10+)上,entropy_avail
通常会返回 256(位),这说明您可以从 获得一个 256 位随机数/dev/[u]random
,并且破解它平均需要 2 255 次猜测。
不过,内核报告的 256 值是否真的是熵的正确度量,而不仅仅是可用位数,则是另一回事。Jason Donenfeld(代码的作者/维护者)说“熵估计从根本上来说是不可能的”。
“太低”到底有多低?好吧,如果您想要一个 256 位随机数,而您的生成器的熵小于 256 位,那么它就太低了。另一方面,如果您确信您的生成器已正确实现并且熵值正确,那么您可以组合多个“太低”结果。请注意,/dev/random
在最近的内核(5.6+)中不再阻塞,因此您不能等到获得所需的位数。