我理解了/dev/urandom吗?

75

我一直在阅读关于 /dev/urandom 的内容,据我所知,/dev/random 利用网络数据包时序等多个事件来生成密码学随机数。然而,我是否正确理解了 /dev/urandom 使用 PRNG,并使用从 /dev/random 中获取的种子数?还是说只要有位元,它就会一直使用 /dev/random -- 当位元用尽时,它会从何处收集的种子转向某些 PRNG 呢?

3个回答

99
urandom 手册中:
随机数生成器会从设备驱动程序和其他来源收集环境噪声进入熵池。该生成器还会估计熵池中的噪声位数。从此熵池中创建随机数。
当读取 /dev/random 设备时,将仅返回熵池中估计数量的随机字节。/dev/random 适用于需要非常高质量的随机性的用途,例如一次性密码本或密钥生成。当熵池为空时,从 /dev/random 读取将阻塞,直到收集到更多环境噪声。
从 /dev/urandom 设备中读取不会阻塞等待更多的熵。因此,如果熵池中没有足够的熵,则返回的值在理论上容易受到驱动程序使用算法的加密攻击的影响。尽管当前未公开的文献中没有介绍如何实现此类攻击,但在理论上可能存在这样的攻击。如果您的应用程序关注此问题,请改用 /dev/random。
这两种方法都使用伪随机数生成器 (PRNG),虽然使用环境数据和熵池使得破解 PRNG 极其困难,除非同时也收集到完全相同的环境数据。
作为一个经验法则,没有专门的昂贵硬件从量子事件等收集数据,就没有真正的随机数生成器 (即产生真正不可预测的数字的 RNG)。但是对于加密目的,/dev/random 或 /dev/urandom 将足够使用 (方法用于 CPRNG,即加密伪随机数生成器)。

/dev/random的熵池和阻塞读操作被用作安全措施,以确保无法预测随机数;例如,如果攻击者耗尽了系统的熵池,虽然在今天的技术水平下高度不可能,但他仍可能预测长时间未重新种子化的/dev/urandom的输出(但这也需要攻击者耗尽系统收集更多熵的能力,这也是极其不可能的)。


2
@Lie,那么操作系统在哪里存储/dev/random的位?它们存储这些位的数量是否有限制? - Pacerier
@Pacerier,random.c的manpage和相应的源代码都有很好的注释,非常有趣:http://git.kernel.org/cgit/linux/kernel/git/torvalds/linux.git/tree/drivers/char/random.c - ijustlovemath
@LieRyan你提到了一般的经验法则。你能否推荐一些可靠的来源,以供参考? - Romeo Sierra

33
实际上,在实际应用中您需要的是FreeBSD的/dev/urandom提供的功能:它将从/dev/random读取足够长度的初始种子,然后使用PRNG。因此,它可能会在最初阻塞(就在系统启动后),但一旦收集到足够的熵,它就不会再阻塞。这提供了大多数加密协议所需的随机性水平,同时不会过度阻塞。

Linux的/dev/urandom类似,只是它永远不会阻塞,因此如果在启动后立即使用它,则可能会冒返回低质量随机数的风险。另一方面,/dev/random可能会在启动后很长一段时间内一直阻塞,这也是一个问题。我经常看到服务器神秘地停止工作,因为某些软件坚持使用/dev/random,而没有键盘的服务器无法获取足够的熵。

通常的Linux发行版在关机时保存从/dev/urandom获取的随机种子,并在下次启动时重新注入,从而保证了由/dev/urandom提供的随机数的质量。只有在安装操作系统时,加密质量才成为一个问题,通常这不是因为安装涉及多次与执行安装的人类进行交互,产生了大量的熵。

总之,在Linux和FreeBSD下,您应该使用/dev/urandom而不是/dev/random


考虑到 /dev/random 被认为比 /dev/urandom 不安全,难道不能建议由于初始种子依赖于 /dev/random,这是一种不太安全的方法吗? - monokrome
3
/dev/urandom比起没有/dev/urandom更加安全,因为当熵耗尽时,/dev/urandom不会阻塞。 - Demi
8
@Demetri - 你刚刚说过/dev/urandom比自己不安全。 - Todd Lehman
1
@ToddLehman 抱歉,我的意思是 /dev/random 在理论上更安全。 - Demi
3
现在Linux有一个getrandom系统调用来实现此目的。 :) - Scott Arciszewski

9

引用这里

/dev/random在熵池耗尽后会阻塞。它会一直阻塞,直到可以从可用的熵源收集到更多数据。这可能会减慢随机数据生成的速度。

/dev/urandom不会阻塞。相反,它将重用内部池来产生更多伪随机位。


当:

  • 你只需要一个包含随机数据的大文件进行某种测试。
  • 你正在使用dd命令通过替换为随机数据来抹掉磁盘上的数据。
  • 几乎在任何其他情况下,你没有真正好的理由使用/dev/random

当:

  • 随机性对于你应用中的密码学安全至关重要 - 一次性密码、密钥生成。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接