3. 随机数与密钥生成测试
密码系统的安全性最终可以归结为一个问题:密钥是否真的不可预测。无论分组密码算法本身多么健壮,如果密钥来自一个可被猜测或可被复现的随机源,整个安全体系就会在第一步崩塌。随机数与密钥生成测试因此不是"锦上添花"的合规项,而是密码应用测试中最需要优先验证的环节。本节围绕熵源评估、DRBG(确定性随机比特生成器)测试、密钥生成合规性、弱随机性检测以及密钥生命周期测试五个要点展开,重点说明每一项"测什么、怎么测、看什么结果"。
熵源评估:从物理噪声到可用熵
熵源是随机性的物理起点,常见形式包括环形振荡器抖动、热噪声、时钟抖动、磁盘寻道时间抖动、中断到达间隔等。熵源评估的核心不是"输出看起来随机",而是估计其真实熵含量。工程上通常采用最小熵(min-entropy)而非香农熵来度量,因为攻击者最关心的是最可能出现的那个输出值。
评估方法上,NIST SP 800-90B 给出了较完整的框架:先对原始噪声样本做 IID 性检验(如卡方检验、游程检验、最长游程检验),若通过则按 IID 轨道用频率统计估计最小熵;若不通过,则需按非 IID 轨道使用十种估计器(如碰撞估计器、马尔可夫估计器、压缩估计器、最长重复子串估计器等)取最小值作为熵下界。测试时需采集足够长的原始样本,例如连续采集 1,000,000 个比特或更多,并记录采样率、温度、电压等环境条件,因为熵源在不同工况下的表现可能显著不同。
一个常见的误区是把"通过随机性统计检验"等同于"熵足够"。统计检验只能说明输出没有明显偏差,无法证明不可预测性。熵源评估必须回到物理模型和最小熵估计,而不是停留在通过率上。
DRBG测试:确定性扩展是否可信
DRBG 把有限的熵扩展为任意长度的随机比特流,其安全性依赖内部状态不可预测以及输出不可从先前输出反推。测试 DRBG 时,重点验证三件事:一是种子注入与重播种(reseed)机制是否正确,包括种子长度、熵输入、附加输入(personalization string)的处理;二是状态更新函数是否满足前向保密与后向保密要求,即拿到当前状态无法推出过去或未来的输出;三是输出是否通过统计检验且不存在可预测结构。
以基于 HMAC 的 DRBG 为例,测试时可构造固定熵输入与固定 nonce,检查相同输入是否产生相同输出(确定性验证),再改变一个比特观察输出是否雪崩式变化。同时应验证 reseed 计数器是否在达到阈值后强制重播种,以及请求长度超过单次上限时是否正确拒绝或分块处理。对于 CTR_DRBG,还需检查计数器是否在每次生成后正确递增、是否会在状态更新时重新生成密钥。
密钥生成合规性:算法、长度与格式
密钥生成合规性检查的是"生成的密钥是否符合所用算法和场景的要求"。这包括:RSA 密钥的模长(如不低于 2048 位)、素性检验方式(Miller-Rabin 轮数、是否使用强素数)、公钥指数取值;ECC 密钥的曲线选择(如 P-256、SM2 推荐曲线)、基点有效性、私钥是否落在合法区间 [1, n-1];对称密钥的长度(AES-128/256、SM4 的 128 位)以及是否由合规 DRBG 产生。
测试时不能只看密钥长度,还要检查生成过程是否引入了偏差。例如某些实现用 random() % n 方式取模,会引入模偏差导致私钥分布不均;正确做法是拒绝采样或使用足够宽的随机数再取模。此外,密钥的编码格式(PEM/DER、PKCS#8、SEC1)和参数完整性也应纳入检查,避免出现缺少曲线参数或公钥点不在曲线上的情况。
弱随机性检测:找出可预测的痕迹
弱随机性检测面向的是"已经生成或正在生成的随机数/密钥",目标是发现可预测、可复现或低熵的模式。常用手段包括:
- 统计检验套件:NIST STS、Dieharder、TestU01 的 SmallCrush/Crush/BigCrush,关注 p 值分布是否均匀、是否有大量检验失败。
- 重复与碰撞检测:在大量密钥或随机数中查找重复值、近似值、固定前缀或固定后缀。
- 时间与进程相关性:检查不同进程、不同时间、不同机器生成的随机数是否存在关联,例如同一启动时刻的种子是否相同。
- 已知弱种子库比对:将生成结果与常见弱随机数库(如时间戳种子、PID 种子、固定种子)比对。
实际案例中,弱随机性往往表现为"启动早期熵不足"。例如嵌入式设备在开机后立即生成密钥,此时熵池尚未积累足够噪声,输出可能高度可预测。测试时应模拟冷启动、低负载、无网络等条件,观察密钥生成是否被阻塞或是否退化为弱随机。
密钥生命周期测试要点
密钥不是生成完就结束,其生命周期包括生成、存储、使用、更新、归档、销毁。测试要点应覆盖:
| 阶段 | 测试关注点 | 典型判断依据 |
|---|---|---|
| 生成 | 熵源、DRBG、算法参数、格式 | 最小熵达标、参数合规、无模偏差 |
| 存储 | 是否明文落盘、是否受保护 | 密钥文件权限、是否加密存储、是否可被非授权读取 |
| 使用 | 是否越权使用、是否泄露到日志 | 调用接口鉴权、日志中无密钥明文 |
| 更新 | 是否按策略轮换、旧密钥是否失效 | 轮换周期、旧密钥不可再用于新数据 |
| 销毁 | 是否可恢复、内存是否清零 | 销毁后无法恢复、内存无残留 |
生命周期测试中最容易被忽略的是"更新"和"销毁"。很多系统生成了强密钥,却长期不轮换,或在销毁时只删除文件引用而未覆写存储介质。测试时应实际执行一次轮换和销毁,验证旧密钥确实无法再解密新数据,且销毁后通过取证手段无法恢复。
把上述五个要点串起来看,随机数与密钥生成测试的主线是:熵源提供不可预测的物理基础,DRBG 将其扩展为可用比特流,密钥生成按算法要求产出合规密钥,弱随机性检测负责发现异常痕迹,生命周期测试确保密钥从生到死都处于受控状态。任何一环出现弱化,都会让后续的密码运算失去意义。测试时建议先做熵源与 DRBG 的底层验证,再做密钥生成合规性检查,最后用弱随机性检测和生命周期测试做交叉确认,形成完整的证据链。