/dev/random
/dev/random在类UNIX系统中是一个特殊的设备文件,可以用作随机数发生器或伪随机数发生器。
实现
并不是所有操作系统中的/dev/random的实现都是相同的。以下列举了一些操作系统中的实现。
Linux
Linux内核中的是第一个以背景噪声产生真正的随机数产生的实现,它允许程序访问来自设备驱动程序或其它来源的背景噪声。
1994年,美国程序员曹子德(Theodore Y. Ts'o)第一次在Linux内核中实现了随机数发生器[1][2]。使用了SHA-1散列算法而非密码,以避开法律限制。另一个原因是任意给定的散列或密码加密强度弱,而新随机数发生器在提高了密码强度。
发生器有一个容纳噪声数据的熵池,在读取时,/dev/random
设备会返回小于熵池噪声总数的随机字节。/dev/random
可生成高随机性的公钥或一次性密码本。若熵池空了,对/dev/random
的读操作将会被阻塞,直到收集到了足够的环境噪声为止[3]。这样的设计使得/dev/random
是真正的随机数发生器,提供了最大可能的随机数据熵,建议在需要生成高强度的密钥时使用。
/dev/random
的一个副本是/dev/urandom
(“unblocked”,非阻塞的随机数发生器[4]),它会重复使用熵池中的数据以产生伪随机数据。这表示对/dev/urandom
的读取操作不会产生阻塞,但其输出的熵可能小于/dev/random
的。它可以作为生成较低强度密码的伪随机数生成器,不建议用于生成高强度长期密码。
/dev/random
也允许写入,任何用户都可以向熵池中加入随机数据。即使写入非随机数据亦是无害的,因为只有管理员可以调用ioctl以增加熵池大小。Linux内核中当前熵的值和大小可以通过访问/proc/sys/kernel/random/
文件夹中的文件得到。
2006年3月,Gutterman、Pinkas和Reinman发表了对Linux随机数发生器的详细密码学分析[5],其中提出了该发生器的几个弱点。也许其中最严重的问题发生在嵌入式系统和Live CD系统,类似路由器和无盘工作站中的应用。在这些系统中,引导状态是可预测的,且环境熵的来源也较为受限。对于有NVRAM的系统,他们建议在关机时保存一部分随机数发生器的状态,使得在下次开机时可以恢复这些状态。对于路由器而言,网络数据是熵的主要来源,他们认为在重启前后保存和恢复数据可能要求潜在的攻击者要么窃听从路由器投入使用开始全部的网络信息,或直接获取路由器的内部状态。他们写道,这个问题对于无线路由器而言尤其关键,因为其网络信息可以远程获取到,并可能用于产生数据加密用密钥的随机发生器。
FreeBSD
FreeBSD操作系统实现了256位的Yarrow算法变体,以提供伪随机数流。与Linux的/dev/random
不同,FreeBSD的/dev/random
不会产生阻塞,与Linux的/dev/urandom
相似,提供了密码学安全的伪随机数发生器,而不是基于熵池。而FreeBSD的/dev/urandom
则只是简单的链接到了/dev/random
。
Yarrow算法的前提是现代的伪随机数发生器的安全性很高,若其内部状态不为攻击者所知,且比熵估计更易理解。在某些情况下,攻击者可以在某种程度上掌握熵的量,例如无盘服务器的熵几乎全部来自于网络,使得它可能易受中间人攻击的影响。算法的种子会被规则的重置:在网络和磁盘负载较轻的系统上,一秒内种子可能被重置数次。
FreeBSD也支持硬件随机数发生器,并在安装了类似硬件时会替代Yarrow算法。
2004年,Landon Curt Noll测试了FreeBSD 5.2.1版本的/dev/random
,发现它不是一个密码学强的随机数发生器,因为其输出在十亿位测试中显示出了多个一致性缺陷。类似的缺陷亦发生在Linux 2.4.21-20,Solaris 8 patch 108528-18和Mac OS X 10.3.5的/dev/random
中[6]。
其它操作系统
/dev/random
和/dev/urandom
也存在于
Solaris[7]、Mac OS X[8]、NetBSD[9]、OpenBSD[10]、Tru 64 UNIX 5.1B[11]、AIX 5.2[12]和HP-UX 11i v2[13]中。与FreeBSD的实现类似,AIX采用了它自身的基于Yarrow的设计,但AIX使用的熵源数量低于标准/dev/random
的实现,并且在系统认为熵池的熵达到足够值时停止填充熵池[14]。
在Windows NT中,ksecdd.sys
提供了类似的功能,但读取特殊文件\Device\KsecDD
并不会提供与UNIX中相同的功能。开发文档中提到的,用于产生密码用随机数据的函数是CryptGenRandom和RtlGenRandom[15][16]。
虽然DOS没有原生的提供类似功能,但有开源的Noise.sys(页面存档备份,存于互联网档案馆)提供了类似功能。该实现与/dev/random
的功能和接口类似,即创建了两个设备,RANDOM$与URANDOM$,也可以通过/DEV/RANDOM$和/DEV/URANDOM$访问。
EGD
EGD(熵收集守护进程,Entropy Gathering Daemon)通常可以在不支持/dev/random
设备的UNIX系统中提供类似的功能。这是一个运行于用户态的守护进程,提供了高质量的密码用随机数据。一些加密软件,例如OpenSSL,GNU Privacy Guard和Apache HTTP服务器支持在/dev/random
不可用的时候使用EGD。
EGD(页面存档备份,存于互联网档案馆),或者类似的软件,例如prngd(页面存档备份,存于互联网档案馆),可以从多种来源收集伪随机的熵,并对这些数据进行处理以去除偏置,并改善密码学质量,然后允许其它程序通过UNIX域套接口(通常使用/dev/egd-pool
),或TCP套接口访问其输出。该程序通常使用建立子进程的以查询系统状态的方式来收集熵。它查询的状态通常是易变的、不可预测的,例如CPU、I/O、网络的使用率,也可能是一些日志文件和临时目录中的内容。
参考文献
- ^ Jack Lloyd. On Syllable's /dev/random. December 9, 2008 [2009-04-27]. (原始内容存档于2009-04-29).
- ^ /dev/random. everything2.com. June 8, 2003 [2009-04-27]. (原始内容存档于2009-04-29).
- ^
Linux用户手册:urandom (4)
- ^ random(4) - Linux manual page. [2010-10-09]. (原始内容存档于2010-04-30).
- ^ Zvi Gutterman; Benny Pinkas, Tzachy Reinman. Analysis of the Linux Random Number Generator (PDF). March 6, 2006 [2008-09-18]. (原始内容存档 (PDF)于2008-10-03).
- ^ BIllion Bit Test: Results and Conclusions, LavaRnd (LavaRnd), 22 Sep 2004 [3 July 2009], (原始内容存档于2007-04-03)
- ^ 存档副本. [2010-10-09]. (原始内容存档于2009-07-31).
- ^ Documentation Archive. [2010-10-09]. (原始内容存档于2010-02-22).
- ^ rnd - NetBSD Manual Pages. [2010-10-09]. (原始内容存档于2016-03-04).
- ^ random(4) - OpenBSD manual pages. man.openbsd.org. [2021-03-21]. (原始内容存档于2021-05-14).
- ^ 存档副本. [2010-10-09]. (原始内容存档于2011-06-07).
- ^ IBM Knowledge Center. [2010-10-09]. (原始内容存档于2013-07-01).
- ^ Software solutions | HP® Official Site. [2010-10-09]. (原始内容存档于2008-12-24).
- ^ Iain Roberts. AIX 5.2 /dev/random and /dev/urandom devices. Lists.gnupg.org. April 25, 2003 [2008-09-18]. (原始内容存档于2012-02-22).
- ^ CryptGenRandom. [2010-10-09]. (原始内容存档于2008-04-23).
- ^ RtlGenRandom. [2010-10-09]. (原始内容存档于2008-10-14).