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

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

评论

另请参见/ dev / urandom中的兰特对于登录密钥是否安全?

交叉发布(并锁定)在crypto.se

sockpuppet.org/blog/2014/02/25/safely-generate-random-numbers

#1 楼

TL; DR

/dev/urandom用于大多数实际用途。

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

Linux

从历史上看,同时引入了/dev/random/dev/urandom

@DavidSchwartz在评论中指出,在大多数情况下,首选使用/dev/urandom。他和其他人还提供了指向我建议进一步阅读的有关/dev/urandom的出色神话的链接。 />两者均由同一CSPRNG馈送以生成随机性(图2和图3) br />
/dev/random永远不会阻塞,从/dev/urandom读取会停止进程执行。
在极少数情况下,启动后不久,CSPRNG可能没有足够的熵来正确植入,并且/dev/random可能不会产生很高的熵。质量随机性。
如果最初正确地植入CSPRNG,则熵变低不是问题。
在Linux 4.8及更高版本中,CSPRNG不断被重新播种
/dev/urandom不会耗尽熵池(由/dev/urandom使用),但使用上游的CSPRNG输出。
使用/dev/random

规则的例外

在密码栈交换中,何时在Linux中使用/dev/urandom而不是/dev/random
@otus给出了两种用例:


在低熵设备上启动后不久,如果尚未生成足够的熵来正确植入/dev/urandom
生成具有信息理论安全性的一次性垫

如果您担心(1),可以检查/dev/urandom中可用的熵。

如果您正在做(2),您已经知道了:)

注意:您可以检查从/ dev / random读取是否会阻止,但是要当心可能的比赛条件。

替代方法:都不使用!

@otus还指出,/dev/random系统将从getrandom()读取,并且仅在初始种子熵不可用时才阻塞。可以基于/dev/urandom创建新的/dev/urandom设备。

macOS

没关系,如Wikipedia所说:


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


FreeBSD

没关系,就像维基百科所说:


getrandom()只是到/dev/xrandom的链接,并且只有在正确播种之前才阻塞。

NetBSD

使用getrandom(),假设您的系统已从/dev/urandom读取至少一次以确保正确的初始种子。

rnd(4)联机帮助页上说:


/dev/random从不阻塞。

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

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

在运行与Internet或Internet进行通信的任何服务之前,应设计系统以在启动时至少明智地从
/ dev / random中读取一次。否则需要加密,以免
可预测地生成密钥。


评论


BSD:使用/ dev / urandom-除非在OpenBSD上没有/ dev / urandom这样的东西。 OpenBSD具有/ dev / arandom,但不应使用它,而应使用arc4random(3)函数。也许应该将关于随机设备和功能的建议留给实际上了解所有内容的人?

–佐藤桂(SatōKatsura)
16-11-18在6:58



@SatoKatsura好收获。更新到FreeBSD以反映报价。您将如何建议确定这些人是谁?

–汤姆·黑尔
16-11-18在7:01



学历?经过同行评审的工作?

–佐藤桂(SatōKatsura)
16年11月18日在7:02

“ / dev / random在熵用尽时会阻塞”-在Linux上,这取决于打开设备的方式。如果打开标志包括O_NONBLOCK,那么它将不会阻塞。如果没有熵,则调用将立即返回并指示已读取0个字节。

–user56041
17年7月21日在15:54



@TomHale该行为在IMO中并不奇怪。如果/ dev / random仅(例如:) 60个字节,则dd将为您提供60个字节的文件。在相同的场景中使用head可能看起来像是永远挂了。两者都没有做您想做的事,但是,至少对我来说,很明显,脑袋没有做预期的事情。

– Ryan J
18年4月23日在3:34

#2 楼

传统上,/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。有一篇很好的论文解释了在生成RSA密钥且熵不足时使用/dev/urandom的后果。阅读挖掘您的P和Q。

评论


在macOS上不再是草了:apple.stackexchange.com/questions/362531/…

–伍德斯托克
19/12/9在15:09

#3 楼

这在某种程度上是“我也是”的答案,但这加强了汤姆·黑尔的建议。完全适用于Linux。


使用/dev/urandom

不要使用/dev/random


根据Theodore Ts' o在Linux Kernel Crypto邮件列表中,已弃用/dev/random已有十年了。摘自Re:[RFC PATCH v12 3/4] Linux随机数生成器:


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


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

问题在Debain系统(i686,x86_64,ARM和MIPS)上非常严重,我们要求GCC编译场为他们的测试机安装rng-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。模块。