/ dev / random是否真的是随机的?
例如,它可以用来生成一次性密钥?
此外,它的来源是什么?它如何被用于生成x和y之间的随机数?
这个宇宙中唯一可以真正考虑的东西就是基于量子效应的宇宙。 常见的例子是放射性衰变。 对于某些原子,你只能确定半衰期,但你不能确定哪个原子核会在下一个分裂。
关于/dev/random
- 取决于实现。 在Linux中,它用作熵源:
Linux内核通过键盘定时,鼠标移动和IDE定时生成熵,并通过特殊文件/ dev / random和/ dev / urandom将随机字符数据提供给其他操作系统进程。
维基
这意味着它比算法随机生成器更好,但它也不完美。 熵可能不是随机分布的,可能有偏差。
这是哲学。 实践是,Linux /dev/random
对于绝大多数任务来说足够随机。
有些随机发生器的实现具有更多的熵源,包括音频输入噪声,CPU温度传感器等。无论如何,它们都不是真实的。
有一个有趣的网站,你可以得到真正的随机数,由放射性衰变产生。
严格地说, /dev/random
并不是完全随机的。 硬件资源上的/dev/random
feed以某种方式被认为是不可预测的; 那么它使用函数(主要是散列函数)混合这些数据,这些函数也被假定为单向函数。 因此, /dev/random
的“真随机性”因此与混合函数的固有安全性相关,安全性不如其他任何加密基元保证的安全性,特别是隐藏在/dev/urandom
的PRNG。
/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
,你会活得更长,更快乐。 即使是一次性垫子。
(为了完整/dev/urandom
,在Linux上实现了/dev/urandom
:即使从前一次启动开始它还没有收集到任何熵,它将永远不会阻塞。分布通过创建一个“随机种子”来避免这个问题。安装时间,使用/dev/random
,并使用该种子在每次开机初始化所使用的PRNG /dev/urandom
;一个新的随机种子立即再生时下次开机时这确保了/dev/urandom
始终工作在足够大的内部种子/dev/urandom
的FreeBSD实现将阻塞,直到达到给定的熵阈值,这更安全。)
如果在熵池中没有足够的随机数据,则/dev/random
会阻塞,而/dev/urandom
不会。 相反, /dev/urandom
将回退到PRNG(内核文档)。 从相同的文档:
随机数发生器[熵池]将来自设备驱动器和其他源的环境噪声收集到熵池中。
所以/dev/random
不是算法的,就像PRNG一样,但它也可能不是“真正的随机”。 鼠标移动和按键时间往往遵循模式,可用于漏洞利用,但您必须权衡风险与您的使用情况。
要使用/dev/random
获取x
和y
之间的随机数,假设您对32位整数感到满意,可以查看Java java.util.Random类执行此操作的方式( nextInt()
) ,用适当的代码替代nextBytes()
方法的/dev/random
来读取。