关于 /dev/urandom 的流言终结
| 2019-05-05 11:49:00 评论: 0
有很多关于 /dev/urandom
和 /dev/random
的流言在坊间不断流传。然而流言终究是流言。
本篇文章里针对的都是近来的 Linux 操作系统,其它类 Unix 操作系统不在讨论范围内。
/dev/urandom
不安全。加密用途必须使用 /dev/random
事实:/dev/urandom
才是类 Unix 操作系统下推荐的加密种子。
/dev/urandom
是 伪随机数生成器 (PRND),而 /dev/random
是“真”随机数生成器。
事实:它们两者本质上用的是同一种 CSPRNG (一种密码学伪随机数生成器)。它们之间细微的差别和“真”“不真”随机完全无关。(参见:“Linux 随机数生成器的构架”一节)
/dev/random
在任何情况下都是密码学应用更好地选择。即便 /dev/urandom
也同样安全,我们还是不应该用它。
事实:/dev/random
有个很恶心人的问题:它是阻塞的。(参见:“阻塞有什么问题?”一节)(LCTT 译注:意味着请求都得逐个执行,等待前一个请求完成)
但阻塞不是好事吗!/dev/random
只会给出电脑收集的信息熵足以支持的随机量。/dev/urandom
在用完了所有熵的情况下还会不断吐出不安全的随机数给你。
事实:这是误解。就算我们不去考虑应用层面后续对随机种子的用法,“用完信息熵池”这个概念本身就不存在。仅仅 256 位的熵就足以生成计算上安全的随机数很长、很长的一段时间了。(参见:“那熵池快空了的情况呢?”一节)
问题的关键还在后头:/dev/random
怎么知道有系统会多少可用的信息熵?接着看!
但密码学家老是讨论重新选种子(re-seeding)。这难道不和上一条冲突吗?
事实:你说的也没错!某种程度上吧。确实,随机数生成器一直在使用系统信息熵的状态重新选种。但这么做(一部分)是因为别的原因。(参见:“重新选种”一节)
这样说吧,我没有说引入新的信息熵是坏的。更多的熵肯定更好。我只是说在熵池低的时候阻塞是没必要的。
好,就算你说的都对,但是 /dev/(u)random
的 man 页面和你说的也不一样啊!到底有没有专家同意你说的这堆啊?
事实:其实 man 页面和我说的不冲突。它看似好像在说 /dev/urandom
对密码学用途来说不安全,但如果你真的理解这堆密码学术语你就知道它说的并不是这个意思。(参见:“random 和 urandom 的 man 页面”一节)
man 页面确实说在一些情况下推荐使用 /dev/random
(我觉得也没问题,但绝对不是说必要的),但它也推荐在大多数“一般”的密码学应用下使用 /dev/urandom
。
虽然诉诸权威一般来说不是好事,但在密码学这么严肃的事情上,和专家统一意见是很有必要的。
所以说呢,还确实有一些专家和我的一件事一致的:/dev/urandom
就应该是类 UNIX 操作系统下密码学应用的首选。显然的,是他们的观点说服了我而不是反过来的。(参见:“正道”一节)