随机数生成器

1. 随机数应用

  • 生成密钥,如对称密码和MAC
  • 生成公钥密码对
  • 生成IV
  • 生成nonce
  • 生成盐

2. 随机数的性质

  • 随机性 - 弱伪随机数
  • 不可预测性 - 强伪随机数
  • 不可重现性 - 真随机数

以上性质前者为后者的子集。

随机性

如果伪随机数列不存在统计学偏差,则可认定随机。

GMSSL - 国密SSL实验室提供了随机数检测工具GMTools.jar。

不可预测性

伪随机数生成器的算法是公开的,如果不知道种子,则不能根据已知伪随机数列预测出后面的伪随机数。

英特尔新型CPU的RDRAND指令可以生成不可预测的随即数,方法是基于NIST SP 800-90A中的CTR-DRBG。

不可重现性

仅靠软件无法实现,因为计算机具备有限的内部状态。

凡是具备周期的数列,都不具备不可重现性。

要想生成真随机数列,需要借助物理信息,如温度、声音、鼠标位置、键盘输入间隔等。

目前,利用电路中的热噪声可以生成真随机数列。如英特尔新型CPU的RDSEED指令可以生成不可重现的随机数,随机信号经过AES-CBC-MAC算法处理,生成256 bits随机数据,作为伪随机数生成器的种子。

3. 伪随机数生成器(PRNG)

 seed
  |
  |
  |
+-----------------+
| |	              |
| +->inner state  |
|                 |
|                 |
|      PRNG       |---> random numbers
+-----------------+

内部状态就是PRNG的内存,根据内存值计算出下一个随机数。

内部状态绝不能被外部知晓。

下面介绍一下PRNG的各种生成方法。

杂乱算法

这种方法不可取,因为无法评估随机性。

线性同余

linear congruential method

应用很广泛,但不能用于密码技术。

已知A, C, M为常量,且A, C小于M,随机数列R生成如下:

seed作为内部状态
R0 = (A * seed + C) mod M
R0成为新的内部状态
R1 = (A * R0 + C) mod M

所以说,线性同余法不具备不可预测性,很多语言的随机函数,如C的rand,java的java.util.Random都是不能用于密码技术的。但Java有一个java.security.SecureRandom类。

利用hash函数

Hash函数具有单向性,可用于隐藏内部状态。

PRNG内部状态是一个计数器。

ctr = seed;
R0 = hash(ctr);
ctr += 1;
R1 = hash(ctr);

利用加密算法

相比hash方法,除了计数器初始值还需要一个加密密钥作为PRNG输入,即seed = CTR_IV + key.

ANSI X9.17

相比加密算法,内部状态的更新更复杂一些,PGP使用了这种方法,伪代码如下:

PRNG(iv, key)
{
    static state = iv;
    
    cipher1 = encrypt(key, cur_time);
    cipher2 = encrypt(key, state ^ cipher1);
    cipher3 = encrypt(key, cipher1 ^ cipher2);
    state = cipher3;
    return cipher2;
}    

相关文档:FIPS 171, Key Management Using ANSI X9.17 | CSRC (nist.gov)

4. 攻击方法

  • 窃取种子;
  • 窃取伪随机数池,它存储了后续要使用的种子。
  • 1
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值