Linux中的随机数

Linux中的随机数

在 linux 中 /dev/random 基于“环境变量”,而 /dev/urandom 基于算法和时间。我的问题是:

/dev/random 从哪里收集这些变量。

如果您将两台机器设置为相同的时间(精确到毫秒 - 如果可能)并且具有相同的速度、操作系统等...并且对 /dev/urandom 进行 X 字节数的十六进制转储,它们是否会具有相同的精确值(因为时间相同)?

答案1

/dev/urandom 从哪里收集这些变量。

它可以在所有地方发挥作用,主要是中断计时。例如,如果您有网卡,数据包到达的精确时间将受到网卡上的晶体时基与为 CPU 计时的晶体时基之间的偏移的影响。两个石英晶体振荡器之间的偏移受到微观区域温度变化的影响,这些变化被认为是真正物理随机的。

如果您有一个旋转磁盘,则读取完成的时间取决于磁盘旋转的速度。这受到磁盘表面和磁盘组件内部空气之间的湍流剪切力的影响。虽然这不被认为是真正的物理随机性,但它是任何已知机制完全无法预测或重复的。

如果您将两台机器设置为相同的时间(精确到毫秒 - 如果可能)并且具有相同的速度、操作系统等...并且对 /dev/random 进行 X 字节数的十六进制转储,它们是否会具有相同的精确值(因为时间相同)?

嗯,毫秒还远远不够。你需要与 CPU 测量时间处于同一水平——十亿分之一秒。但当然,必须如此。否则,如果你看到一台机器的状态,你就能 100% 确定另一台机器不可能有相同的状态。而且由于状态应该是随机的,你不应该能够通过查看任何其他机器并 100% 确定地了解该状态。只要实现这一目标的几率足够低(比如,小于 2^100 分之一),那么就完全没问题。

即使你掷两个骰子,每个骰子都有十亿面,它们的结果也可能相同。只要它们每十亿次只有一次结果相同,那就理所当然。

答案2

看一下urandom的手册,特别是描述:

读取时,/dev/random 设备将仅返回熵池中估计的噪声位数内的随机字节。/dev/random 应该适合需要极高质量随机性的用途,例如一次性密码本或密钥生成。当熵池为空时,/dev/random 的读取将被阻止,直到收集到额外的环境噪声。

从 /dev/urandom 设备读取不会因等待更多熵而阻塞。因此,如果熵池中没有足够的熵,则返回的值在理论上容易受到驱动程序使用的算法的加密攻击。目前未分类的文献中没有关于如何做到这一点的知识,但理论上可能存在这样的攻击。如果您的应用程序担心这一点,请改用 /dev/random。

不幸的是,我无法真正回答你的第二个问题,我使用别人可以,但我的猜测是非常很难在两台机器上获得完全相同的结果。

答案3

在 linux 中 /dev/urandom 基于“环境变量”,而 /dev/random 基于算法和时间。

这两个假设都是错误的。

根据随机(4) - Linux 手册页1/dev/random 将来自设备驱动程序和其他来源的环境噪声收集到熵池中

鼠标就是此类设备的一个例子。2尝试执行

head -c 1024 /dev/random | base64

清除熵池(几秒后中止),然后

head -c 40 /dev/random | base64

从 读取 40 个字节/dev/random。不执行任何操作,观察是否head停止对数时间,因为池中没有新的熵。

中止,然后执行

head -c 40 /dev/random | base64

再次。这一次,快速地从左到右移动鼠标。head将快速完成其任务。

再次,根据随机(4) - Linux 手册页/dev/urandom使用相同的熵池,但不会阻塞。如果熵池不够大,它会回退到伪随机数生成器(PRNG)创建更多(伪)随机输出。


1实际行为可能因发行版不同而有所差异。

2示例适用于 Ubuntu 12.04。其他发行版可能有所不同。

相关内容