原文地址:http://drops.wooyun.org/papers/9144

0x00 前言


在前两讲中,我们主要对SSL协议中CBC模式的弱安全性进行了系统的介绍。这一讲中我们对用于生成SSL中所用密钥的PRNG做一点简单介绍。

0x01 什么是PRNG?


PRNG(pseudo Random Noise Generation),即伪随机噪声生成,用于生成各种密码学操作中所需的随机数。

一般而言,Linux系统中的PRNG(简称为LRNG)可以被分为3个异步的部分。第一部分把系统事件转化为bit来表示潜在的熵;第二部分把这些bit加入到随机数生成池;第三部分使用连续的SHA-1操作处理生成池中的bit来产生输出,得到的反馈依然被放入生成池中来更新它。

每个从系统事件得到的随机性都被收集为两个32-bit的word。第一个word包含事件发生的时间,第二个word是事件的值,通常是一个按键、鼠标移动或者驱动访问的编码。

LRNG使用一个计数器来计算加入到生成池中物理随机性的估算值,这个值用一个不同事件发生频率的函数来计算。这个值被表示为熵。

Linux系统中PRNG的结构抽象如下图所示:

0x02 Linux中PRNG的运作原理


0x03 弱PRNG对SSL的影响


OpenSSL的PRNG是一个确定性函数,知道输入和调用次序的攻击者可以预测输出。为了使PRNG安全,熵池必须从/dev/random或者其它攻击者不知道的熵源中取种。2006年,在Debian Linux发布版本中的OpenSSL增加了一个漏洞修复,而这个漏洞修复引入了一个新的漏洞,它在修复另一个漏洞时把生成随机数选种过程的代码给删掉了,这导致初始选种时使用到的唯一的随机值是当前进程ID-pid,Linux平台默认最大进程号是32,768,所以生成随机数的种子值范围很小。这个漏洞到2008年才被发现,受影响的Debian Linux版本的可用熵都很有限,产生的公私钥对是可预测的,这样导致生成的SSL协议中使用的服务器私钥具有脆弱性。由于漏洞存在,攻击者可以事先生成公私钥对,一旦发现有跟公钥匹配的就知道了对应私钥。加州大学圣地亚哥分校的研究人员在漏洞发布不久对流行的SSL服务器进行扫描,发现1.5%左右的服务器使用了弱密钥证书。

事实上,因为弱PRNG生成的RSA和DSA弱密钥在TLS和SSH服务器中广泛存在。在2012年的一项调查中发现,0.75%的TLS证书因为熵不足共享了密钥,其他还有1.7%的设备采用了相同实现,很可能也存在此类问题。0.5%的TLS主机和0.03%的SSH主机RSA私钥可被获取,因为它们的公钥存在共享公因子现象。RSA公钥的分解是很困难的,但是如果两个公钥共享了某一素因子,那么只要计算出这个素因子,就可以将这两个公钥分解,从而计算出对应的私钥。

这一现象是由于PRNG在生成随机数时,如果用于产生RSA公钥的两个随机数都是在熵源不足的情况下生成的,那么采用相同实现的设备就可能生成两个相同的素因子,导致对应的私钥相同。如果两个随机数中,仅有一个是在熵源不足的情况下生成,那么两台采用相同实现的不同设备生成的RSA公钥就可能共享一个素因子,导致这两个RSA公钥均可很容易地被分解。

弱PRNG导致的弱RSA和DSA密钥问题在嵌入式设备如路由器、闭路电视等中也广泛存在,因为这类设备的熵源有限(缺少鼠标键盘等熵源)。关于嵌入式设备中弱密钥的问题具体可以参考USENIX Security 14年的文章A Large-Scale Analysis of the Security of Embedded Firmwares,由于导致弱密钥的原理相同,这里就不多做介绍了。