何时使用 /dev/random 与 /dev/urandom

Tom*_*ale 129 devices random

我应该使用/dev/random还是/dev/urandom

在哪些情况下我更喜欢一种?

Tom*_*ale 126

TL; 博士

使用/dev/urandom最实用的目的。

更长的答案取决于您运行的 Unix 风格。

Linux

在历史上,/dev/random并同时/dev/urandom被引入。

正如@DavidSchwartz在评论中指出的那样/dev/urandom在绝大多数情况下首选使用。他和其他人还提供了一个链接,指向我推荐进一步阅读的优秀Myths about/dev/urandom文章。

总之:

  • 手册页是误导。
  • 两者都由相同的 CSPRNG馈送以生成随机性(图 2 和图 3
  • /dev/random当它用完熵时阻塞,因此读取/dev/random可以停止进程执行。
  • 熵的量是保守估计的,但不计算
  • /dev/urandom 永远不会阻塞。
  • 在极少数情况下,在启动后不久,CSPRNG可能没有足够的熵来正确播种,并且/dev/urandom可能无法产生高质量的随机性。
  • 如果 CSPRNG 最初被正确播种,那么熵低不是问题。
  • CSPRNG 不断被重新播种。
  • 在 Linux 4.8 及更高版本中,/dev/urandom不会耗尽熵池(由 使用/dev/random),而是使用来自上游的 CSPRNG 输出。
  • 使用/dev/urandom.

规则的例外

在加密堆栈Exchange的时候使用/dev/random/dev/urandomLinux中 @otus给出了两个用例

  1. 在低熵设备上启动后不久,如果尚未生成足够的熵来正确播种/dev/urandom

  2. 生成具有信息论安全性的一次性密码本

如果您担心 (1),您可以检查/dev/random.

如果你正在做 (2) 你就会知道它:)

注意:您可以检查从 /dev/random 读取是否会阻塞,但要注意可能的竞争条件。

替代方案:既不使用!

@otus 还指出,如果初始种子熵不可用,getrandom()系统将从中读取/dev/urandom并且仅阻塞。

更改/dev/urandom使用getrandom()存在问题,但可以想象,新/dev/xrandom设备是基于getrandom().

苹果系统

没关系,正如 维基百科所说

macOS 使用基于 SHA1 的160 位Yarrow。/dev/random 和 /dev/urandom 没有区别;两者的行为相同。Apple 的 iOS 也使用 Yarrow。

FreeBSD

没关系,正如维基百科所说

/dev/urandom只是一个链接/dev/random,只有在正确播种之前才会阻止。

这意味着在启动后,FreeBSD 足够聪明,可以等到收集到足够的种子熵,然后再提供永无止境的随机良性流。

NetBSD

使用/dev/urandom,假设您的系统已至少读取一次 from/dev/random以确保正确的初始播种。

RND(4)用户手册说

/dev/urandom 从不阻塞。

/dev/random有时会阻塞。如果已知系统状态是可预测的,将在启动时提前阻塞。

应用程序应该/dev/urandom在需要随机生成的数据时读取,例如用于模拟的加密密钥或种子。

系统应该被设计为/dev/random在运行任何与互联网通信或以其他方式需要加密的服务之前,在启动时至少明智地读取一次 ,以避免可预测地生成密钥。

  • @SatoKatsura 好收获。更新到 FreeBSD 以反映报价。您建议如何确定这些人是谁? (3认同)
  • 学历?同行评审的工作? (3认同)
  • _BSD:使用`/dev/urandom`_ - 除了OpenBSD 上没有`/dev/urandom` 这样的东西。OpenBSD 有 `/dev/arandom`,但你不应该使用它,你应该使用 `arc4random(3)` 函数来代替。也许关于随机设备和功能的建议应该留给真正了解这一切的人? (2认同)
  • @TomHale IMO 的行为并不那么令人惊讶。如果 `/dev/random` 只有(例如:)60 字节,`dd` 会给你一个 60 字节的文件。在同一场景中使用 `head` 可能看起来像是永远挂着。也没有做你想做的事,但是,至少对我来说,更明显的是 `head` 没有做预期的事情。 (2认同)

Kir*_*ski 6

传统上,/dev/urandom和之间的唯一区别/dev/random是当内核认为系统中没有熵时会发生什么 -/dev/random关闭/dev/urandom失败,打开失败。两名司机均从采购熵add_disk_randomness()add_interrupt_randomness()add_input_randomness()/drivers/char/random.c具体请看。

编辑添加:从 Linux 4.8/dev/urandom开始,重新设计以使用 CSPRNG。

那么什么时候应该关闭失败呢?对于任何类型的加密用途,特别是播种 DRBG。有一篇很好的论文解释了/dev/urandom在生成 RSA 密钥和没有足够的熵时使用的后果。阅读挖掘你的 Ps 和 Qs


小智 6

这有点像“我也是”的回答,但它加强了汤姆黑尔的建议。它完全适用于 Linux。

  • /dev/urandom
  • 不要使用 /dev/random

根据 Linux Kernel Crypto 邮件列表上的 Theodore Ts'o 的说法,它/dev/random已被弃用十年。来自回复:[RFC PATCH v12 3/4] Linux 随机数生成器

实际上没有人使用/dev/random。它本质上是一个已弃用的接口;十多年来一直推荐的主要接口是 /dev/urandom,现在是 getrandom(2)。

我们定期进行测试/dev/random,但它经常出现故障。测试执行三个步骤: (1)/dev/random通过在非阻塞模式下请求 10K 字节来耗尽;(2) 在阻塞模式下请求 16 个字节 (3) 尝试压缩块以查看其是否随机(穷人的测试)。测试需要几分钟才能完成。

这个问题在 Debain 系统(i686、x86_64、ARM 和 MIPS)上非常严重,我们要求 GCC Compile Farmrng-tools为他们的测试机器安装包。从在 gcc67 和 gcc68 上安装 rng-tools

我想请求在 gcc67 和 gcc68 上安装 rng-tools。它们是 Debian 系统,并且 /dev/random 在折磨测试使用该设备的库时会在没有 rng-tools 的情况下遭受熵消耗。

BSD 和 OS X 显示正常。问题肯定是Linux。


值得一提的是,Linux 不会记录生成器故障。他们不希望这些条目填满系统日志。迄今为止,大多数故障都是无声的,大多数用户都没有发现。

由于内核将至少打印一条失败消息,因此情况应该很快就会改变。来自[PATCH] 随机:静音编译器警告并修复内核加密邮件列表上的竞争

具体来说,我添加了depends on DEBUG_KERNEL. 这意味着这些有用的警告只会戳其他内核开发人员。这可能正是我们想要的。如果各个相关的开发人员看到来自他们特定子系统的警告,他们将更有动力修复它。分发内核上的普通用户根本不应该看到警告或垃圾邮件,因为通常用户不使用 DEBUG_KERNEL。

我认为从安全工程的角度来看,抑制所有消息是一个坏主意。

许多人不运行调试内核。大多数想要或需要知道问题的用户不会意识到它的发生。考虑一下,我们了解到 systemd 问题的原因是 dmesg 的。

抑制所有配​​置的所有消息会产生比必要更广泛的网络。可能会被检测到并修复的配置可能不会被注意到。如果问题没有被发现,那么它就不会被修复。

我觉得内核正在为某些组织做出政策决定。对于那些拥有实际上无法修复的硬件的人,组织必须根据他们的风险逆境决定该怎么做。他们可能决定接受风险,或者他们可能决定更新硬件。然而,如果没有关于该问题的信息,他们甚至可能没有意识到他们有一个可操作的项目。

最终在线程中最终达成的妥协是每个调用模块至少有一个 dmesg。