目录
12.2 本章学习的内容
- 使用随机数的密码技术
- 随机数的性质
- 伪随机数生成器
- 具体的伪随机数生成器
- 对伪随机数生成器的攻击
12.3 使用随机数的密码技术
随机数的使用场景:
- 生成密钥
- 生成密钥对
- 生成初始化向量
- 生成nonce
- 生成盐
为了不让攻击者看穿而使用随机数。
12.4 随机数的性质
12.4.1 对随机数的性质进行分类
- 随机性
- 不可预测性
- 不可重现性
12.4.2 随机性
杂乱无章并不代表不会被看穿,因此本书将只具备随机性的伪随机数称为“弱伪随机性”。
12.4.3 不可预测性
攻击者在知道过去生成的伪随机数列的前提下,依然无法预测下一个生成出来的伪随机数的性质。不可预测性是通过使用其他的密码技术来实现的。
我们将具备不可预测性的伪随机数称为强伪随机数。
12.4.4 不可重现性
是指无法重现和某伊随机数列完全相同的数列的性质。仅靠软件是无法生成具备不可重现性的随机数列的,因为运行软件的本身仅具备有限的内部状态。
12.5 伪随机数生成器
随机数可以通过硬件来生成,也可以通过软件来生成。
通过硬件生成的随机数列,是根据传感器收集的热量、声音的变化等事实上无法预测和重现的自然现象信息来生成的。像这样的硬件设备就称为随机数生成器。
而可以生成随机数的软件则称为伪随机数生成器。因为仅靠软件无法生成真随机数,因此要加上一个“伪”字。
伪随机数生成器的结构
伪随机数生成器具有“内部状态”,并根据外部输入的“种子”来生成伪随机数列。
伪随机数生成器的内部状态
伪随机数生成器的内部状态,是指伪随机数生成所管理的内存中的数组。当有人对伪随机数生成器发出“给我一个伪随机数”的请求时,伪随机数生成器会根据内存中的数值(内部状态)进行计算,并计算结果作为伪随机数输出。随后,为了响应下一个伪随机数请求,伪随机数生成器会改变自己的内部状态。因此,将根据内部状态计算伪随机数的方法和改变内部状态方法组合起来,就是伪随机数生成的算法。
由于内部状态决定了下一个生成的伪随机数,因此内部状态不能被攻击者知道。
伪随机数生成器的种子
为了生成伪随机数,伪随机数生成器需要称为种子(seed)的信息。伪随机数的种子是用来对伪随机生成器内部状态进行初始化的。
伪随机数的种子是一串随机的比特序列,根据种子就可以生产出专属于自己的伪随机数列。伪随机数生成器是公开的,但种子是需要自己保密的,这就好像密码算法是公开的,但密钥只能自己保密。由于种子不可以被攻击者知道,因此不可以使用容易被推测的值,例如不可以用当前时间作为种子。
密码的密钥与伪随机数的种子之前的对比对请参考下图:
12.6 具体的伪随机数生成器
- 杂乱的方法
- 线性同余法
- 单向散列函数法
- 密码法
- ANSI X9.17
- 其他算法
12.6.1 杂乱的方法
如果只是把算法搞得复杂,是无法用于密码技术。
无法判断是否具备不可预测性。
12.6.2 线性同余法
是一种使用很广泛的伪随机数生成器算法。 但是,不能用于密码技术。
线性同余法,是将当前的伪随机数值乘以A再加上C,然后除以M得到的余数作为下一个随机数。不具备不可预测性,因此不可以将线性同余法用于密码技术。
12.6.3 单向散列函数法
可以用于密码技术。伪随机数生成器。
单向散列函数的单向性是支撑伪随机数生成器不可预测性的基础。
12.6.4 密码法
可以用于密码技术。伪随机数生成器。
密码的机密性是支撑伪随机数生成器不可预测性的基础。
12.6.5 ANSI X9.17
关于用密码实现伪随机数生成器的具体方法,在ANSI X9.17和ANSI X9.31的附录中进行了描述。
12.6.5 其他算法
梅森旋转法:和线性同余法一样,不可用于密码技术。
ruby和Java中:
Random类:不可用于密码
SecureRandom类:可用于密码
能否用于密码技术:是否具备不可预测性。 一般在算法的说明中,也会写明是否用于安全相关用途。
12.7 对伪随机数生成器的攻击
12.7.1 对种子进行攻击
伪随机数的种子,不可被攻击者获取。
12.7.2 对随机数池进行攻击
随机数池不可被攻击者知道。