在类UNIX操作系统中,/dev/random是一个特殊的设备文件,可以用作随机数发生器或伪随机数发生器。它允许程序访问来自设备驱动程序或其它来源的背景噪声。并不是所有操作系统中的/dev/random的实现都是相同的,而Linux是第一个以背景噪声产生真正的随机数的实现。
Linux
1994年,曹予德第一次在Linux的内核空间中实现了随机数发生器[1][2]。 该实现使用了SHA-1散列算法,而不是密码,以避免随机数产生器编码地的法律限制。该实现在设计时,假定任意给定的散列或密码最终都可能被发现是弱的,因此它可以耐受任意形式的这些弱点。
在这个实现中,发生器保存了来自熵池中噪声的数据位数的估计值,而随机数是从该熵池中创建的。在读取时,/dev/random设备只会返回熵池中噪声数据中的随机字节。/dev/random应当可以适用于要求非常高质量随机性的应用,例如产生公钥或一次性密码本。若熵池空了,对/dev/random的读操作将会被阻塞,直到收集到了足够的环境噪声为止[3]。
这样的设计使得/dev/random是真正的随机数发生器,提供了最大可能的随机数据熵,建议用于产生保护高价值或长保护周期的密钥。
/dev/random的一个副本是/dev/urandom ("unlocked",非阻塞的随机数发生器[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中。
其它操作系统
/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$访问。
阅读(11881) | 评论(0) | 转发(0) |