/dev/random 被认为是真正随机的吗?
例如,它可以用来生成一次性密码本密钥吗?
另外,它的来源是什么以及如何使用它来生成 x 和 y 之间的随机数?
For instance, could it be used to generate a one-time pad key?
Also, what are its sources and how could it be used to generate a random number between x and y?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
严格来说,
/dev/random
并不是真正完全随机的。/dev/random
以假设在某种程度上不可预测的硬件源为基础;然后它使用函数(主要是哈希函数)混合这些数据,这些函数也被假设为单向的。因此,/dev/random
的“真正的随机性”与混合函数的固有安全性相关,这种安全性并不比任何其他加密原语的安全性得到更多保证,特别是隐藏在/dev/urandom
。/dev/random
和/dev/urandom
之间的区别在于,前者会尝试维持对其熵的估计(这意味着“疯狂的猜测”)已经聚集,并且将拒绝输出比这更多的比特。另一方面,/dev/urandom
很乐意从它拥有的熵中生成兆字节的数据。两种方法之间的安全差异是没有意义的,除非您假设“经典”加密算法可以被破解,并且您使用极少数信息论算法之一(例如 OTP 或 Shamir 的秘密分享);即使如此,只有当混合函数仍然被认为是单向的时,
/dev/random
才可能被认为比/dev/urandom
更安全,即与可以破解经典密码算法的想法不兼容。因此,在实践中甚至在理论上,没有任何区别。您可以将/dev/urandom
的输出用于 OTP,并且它不会因为/dev/urandom
内部的任何结构而被破坏——所获得的实际管理流将是弱点(尤其是长时间存储)。另一方面,/dev/random
有非常现实的实际问题,即它可能会在不合时宜的时刻发生阻塞。当自动化操作系统安装阻塞(几个小时!)时,这真的很令人讨厌,因为 SSH 服务器密钥生成坚持使用 /dev/random 并不必要地因熵而停滞。有许多应用程序将
/dev/random
视为一种仪式,就好像它比/dev/urandom
“更好”,可能在业力层面上。这是完全错误的,尤其是当 alea 与经典加密算法一起使用时(例如,生成 SSH 服务器公钥)。不要那样做。相反,使用/dev/urandom
你会活得更长久、更快乐。即使是一次性垫。(为了完整起见,在 Linux 上实现的
/dev/urandom
有一个怪癖:它永远不会阻塞,即使它自上次以来根本没有收集任何熵发行版通过在安装时使用/dev/random
创建“随机种子”来避免此问题,并在每次启动时使用该种子来初始化/dev/urandom 使用的 PRNG。
; 立即重新生成一个新的随机种子,以供下次启动。这确保了/dev/urandom
始终在足够大的内部种子上工作。 urandom 将阻塞,直到达到给定的熵阈值,这更安全。)Strictly speaking,
/dev/random
is not really completely random./dev/random
feeds on hardware sources which are assumed to be unpredictible in some way; then it mixes such data using functions (hash functions, mostly) which are also assumed to be one-way. So the "true randomness" of/dev/random
is thus relative to the inherent security of the mixing functions, security which is no more guaranteed than that of any other cryptographic primitive, in particular the PRNG hidden in/dev/urandom
.The difference between
/dev/random
and/dev/urandom
is that the former will try to maintain an estimate (which means "a wild guess") of how much entropy it has gathered, and will refuse to output more bits than that. On the other hand,/dev/urandom
will happily produce megabytes of data from the entropy it has.The security difference between the two approaches is meaningless unless you assume that "classical" cryptographic algorithms can be broken, and you use one of the very few information-theoretic algorithms (e.g. OTP or Shamir's secret sharing); and, even then,
/dev/random
may be considered as more secure than/dev/urandom
only if the mixing functions are still considered to be one-way, which is not compatible with the idea that a classical cryptographic algorithm can be broken. So, in practice and even in theory, no difference whatsoever. You can use the output of/dev/urandom
for an OTP and it will not be broken because of any structure internal to/dev/urandom
-- actual management of the obtained stream will be the weak point (especially long-time storage). On the other hand,/dev/random
has very real practical issues, namely that it can block at untimely instants. It is really irksome when an automated OS install blocks (for hours !) because SSH server key generation insists on using/dev/random
and needlessly stalls for entropy.There are many applications which read
/dev/random
as a kind of ritual, as if it was "better" than/dev/urandom
, probably on a karmic level. This is plain wrong, especially when the alea is to be used with classical cryptographic algorithms (e.g. to generate a SSH server public key). Do not do that. Instead, use/dev/urandom
and you will live longer and happier. Even for one-time pad.(Just for completeness, there is a quirk with
/dev/urandom
as implemented on Linux: it will never block, even if it has not gathered any entropy at all since previous boot. Distributions avoid this problem by creating a "random seed" at installation time, with/dev/random
, and using that seed at each boot to initialize the PRNG used by/dev/urandom
; a new random seed is regenerated immediately, for next boot. This ensures that/dev/urandom
always works over a sufficiently big internal seed. The FreeBSD implementation of/dev/urandom
will block until a given entropy threshold is reached, which is safer.)这个宇宙中唯一可以被认为真正的东西是基于量子效应的东西。常见的例子是放射性衰变。对于某些原子,您只能确定其半衰期,但无法确定下一个会分裂的是哪个原子核。
关于
/dev/random
- 这取决于实现。在 Linux 中,它用作熵源:Wiki
这意味着它比算法随机生成器更好,但它是也不完美。熵可能不是随机分布的并且可能有偏差。
这就是哲学。实践是,在 Linux 上,
/dev/random
对于绝大多数任务来说是足够随机的。有些随机生成器的实现具有更多的熵源,包括音频输入上的噪声、CPU 温度传感器等。无论如何,它们都不是真的。
有一个有趣的网站,您可以在其中获取由放射性衰变生成的真正随机数。
The only thing in this universe that can be considered truly is one based on quantum effects. Common example is radioactive decay. For certain atoms you can be sure only about half-life, but you can't be sure which nucleus will break up next.
About
/dev/random
- it depends on implementation. In Linux it uses as entropy sources:Wiki
It means that it is better than algorithmic random generators, but it is not perfect as well. The entropy may not be distributed randomly and can be biased.
This was philosophy. Practice is that on Linux
/dev/random
is random enough for vast majority of tasks.There are implementations of random generators that have more entropy sources, including noise on audio inputs, CPU temperature sensors etc. Anyway they are not true.
There is interesting site where you can get Genuine random numbers, generated by radioactive decay.
如果熵池中没有足够的随机数据,
/dev/random
将阻塞,而/dev/urandom
则不会。相反,/dev/urandom
将回退到 PRNG(内核文档< /a>)。来自相同的文档:所以
/dev/random
不像 PRNG 那样是算法性的,但它也可能不是“真正随机的”。鼠标移动和击键时间往往遵循一定的模式,可用于漏洞利用 但您必须根据您的用例权衡风险。要使用
/dev/random
获取x
和y
之间的随机数,假设您对 32 位整数感到满意,您可以看看 Java java.util.Random 类的做法< /a> (nextInt()
),用适当的代码替换从/dev/random
读取nextBytes()
方法。/dev/random
will block if there's not enough random data in the entropy pool whereas/dev/urandom
will not. Instead,/dev/urandom
will fall back to a PRNG (kernel docs). From the same docs:So
/dev/random
is not algorithmic, like a PRNG, but it may not be "truly random" either. Mouse movements and keystroke timings tend to follow patterns and can be used for exploits but you'll have to weigh the risk against your use case.To get a random number between
x
andy
using/dev/random
, assuming you're happy with a 32-bit integer, you could have a look at the way the Java java.util.Random class does it (nextInt()
), substituting in appropriate code to read from/dev/random
for thenextBytes()
method.