/dev/urandom 和 /dev/random 的区别是什么

目录

linux中提供了 ​​/dev/urandom​​​ 和 ​​/dev/random​​ 两个特殊设备来提供随机数。那么这两个文件有什么区别呢? 要回答这个问题,先需要了解熵这个概念。

linux是根据系统的熵池来产生随机数的。熵池就是系统当前的环境噪音,环境噪音的来源很多,键盘的输入、鼠标的移动、内存的使用、文件的使用量、进程数量等等。 当系统的熵不够大的时候,则系统产生的随机数随机效果就不是很好,也就是说更容易被人猜测出来。

如何查看系统中的熵

通过下面命令可以查看系统熵池的容量:

Shell
cat /proc/sys/kernel/random/poolsiz

结果为:

Shell
409

通过下面命令可以查看系统熵池中拥有的熵数:

Shell
cat /proc/sys/kernel/random/entropy_avail

结果为:

Shell
379

通过下面命令可以查看从熵池中读取熵的阀值,当 ​​entropy_avail​​ 中的熵数少于这个阀值,这读取 ​​/dev/random​会被阻塞:

Shell
cat /proc/sys/kernel/random/read_wakeup_threshol

结果为:

Shell
6

如何快速生成熵

通过开启 ​​haveged​​​ 服务可以快速产生熵。若 ​​entropy_avail​​​ 的值小于1000,则建议安装 ​​haveged​​,否则加密程序会阻塞直到系统有足够的熵后才继续运行。

Shell
pacman -S haveged --noconfir
Shell
resolving dependencies...
looking for conflicting packages...
Packages (1) haveged-1.9.1-4
Total Download Size:  0.04 MiB
Total Installed Size: 0.14 MiB
:: Proceed with installation? [Y/n] 
:: Retrieving packages...
 haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 0.0 B 0.00B/s 00:00 [co  o  o  o  o  o  o  ] 0%
haveged-1.9.1-4-x86_64 41.2 KiB 412K/s 00:00 [----------------------] 100%
(0/1) checking keys in keyring [co  o  o  o  o  o  o  ] 0%
(1/1) checking keys in keyring [----------------------] 100%
(0/1) checking package integrity [co  o  o  o  o  o  o  ] 0%
(1/1) checking package integrity [----------------------] 100%
(0/1) loading package files [co  o  o  o  o  o  o  ] 0%
(1/1) loading package files [----------------------] 100%
(0/1) checking for file conflicts [co  o  o  o  o  o  o  ] 0%
(1/1) checking for file conflicts [----------------------] 100%
(0/1) checking available disk space [co  o  o  o  o  o  o  ] 0%
(1/1) checking available disk space [----------------------] 100%
:: Processing package changes...
(1/1) installing haveged [co  o  o  o  o  o  o  ] 0%
(1/1) installing haveged [----------------------] 100%
:: Running post-transaction hooks...
(1/1) Arming ConditionNeedsUpdate..

然后开启 ​​haveged​​ 服务

Shell
systemctl enable haveged
systemctl start havege

/dev/random 与 /dev/urandom 的区别

​/dev/random​​ 是真随机数生成器,它会消耗熵值来产生随机数,同时在熵耗尽的情况下会阻塞,直到有新的熵生成. 注:网上有关于random具有更好的随机性的说法,这一点存在疑问,请阅读​​How To Safely Generate A Random Number​​​ 和 ​​Myths about /dev/urandom​​​ 这两篇文章。 而 ​​/dev/urandom​是伪随机数生成器,它根据一个初始的随机种子(这个种子来源就是熵池中的熵)来产生一系列的伪随机数,而并不会在熵耗尽的情况下阻塞。 但是 若在系统启动阶段使用 /dev/urandom 则可能存在熵池中还不存在任何熵的情况,这时用 /dev/urandom 产生的随机数是可预测的! 结合这两者的特点,可以看出,除非要在启动启动阶段产生随机数,否则绝大多数情况下还是使用 ​​/dev/urandom​​ 来产生随机数,这样才不会引起程序莫名的挂起。 读取/dev/random,生产随机数的C语言实现:

C
1 #include <stdio.h>
2
3 int main( int argc, char** args )
4 {
5 unsigned long* seed = malloc( sizeof( unsigned long ) );
6 FILE* file = fopen("/dev/random", "r");
7 printf( "%d\n", sizeof( unsigned long ) );
8 int i;
9 for( i = 0; i < 9999; ++i)
10 {
11 fread( seed, 1, sizeof( unsigned long ), file );
12 printf( "%lld\n", *seed );
13 }
14 return 1;
15

可以看到:

当使用​​/dev/random​​​时,会有等待出现;

当使用​​/dev/urandom​​则不会。

运行上述程序,然后

Shell
vm2207:/home/random # cat /proc/sys/kernel/random/entropy_avail
162

才162个,一般有4K多个。 也可以在shell中通过

Shell
head -200 /dev/urandom | cksum
head -200 /dev/urandom | cksum | cut -f1 -d

来获取随机数。

参考:

​http://hi.baidu.com/jrckkyy/blog/item/9e29c9cb8f283f0ebf09e600.html​​​

​http://www.orawh.com/31.html​