密钥生成策略:随机数质量、硬件熵源与安全规范
密钥生成是整个密码系统的基座。基座不稳,上层再坚固也白搭。我刚开始做国密项目时,总以为密钥生成就是把随机数丢进算法里跑一圈就行。后来被某次商用密码检测当头一棒——随机数质量不达标,整个密钥生命周期直接亮红灯。嗯,从那以后我才真正重视起这块。
随机数质量的核心指标
随机数生成器分真随机数生成器(TRNG)和伪随机数生成器(PRNG)。TRNG靠物理熵源,PRNG靠种子+算法扩展。国密对随机数质量的要求,说白了就是一句话:不可预测、不可重现、分布均匀。
我在项目中常用两个关键指标:
- 最小熵(Min-Entropy):衡量每个输出比特真正随机性的下限。国密规范要求最小熵不低于0.5,很多商用密码模块实际会做到0.8以上。
- 统计随机性:通过NIST SP 800-22或者国密GM/T 0005-2021《随机性检测规范》中的15项检测(单比特频数、块内频数、游程、累积和、近似熵等)。只有全通过才算合格。
你想想看,如果随机数生成器内部混入了周期性噪声或者被攻击者注入已知种子,那密钥就形同虚设。我遇到过一台设备,之前跑自检一直过,后来发现是TRNG芯片老化后熵源输出弱化,好在那次是测试环境,没造成实际损失。所以后来我坚持每次上电都要做在线随机数检测。
硬件熵源的类型与选型
硬件熵源是TRNG的物理基础。常见的有:
| 熵源类型 | 原理 | 典型速率 | 国密适配情况 |
|---|---|---|---|
| 热噪声(电阻/晶体管) | 利用半导体中载流子热运动的随机涨落 | 几十~几百Kbps | 国内有CHN-TRNG系列,成熟 |
| 振荡器环(Ring Oscillator) | 多个环形振荡器相位抖动累积 | 几Mbps | FPGA可集成,需专用后处理 |
| 混沌电路 | 非线性电路产生混沌序列 | 较高,可达100Mbps | 部分国产厂商有产品 |
我个人习惯优先选用通过国密认证的TRNG芯片,比如某国产芯片型号SDT_TRNG-1024,它内部集成了自检和健康监测,省去很多开发坑。不过要注意——硬件熵源的原始输出往往带有偏置,需要经过后处理(如冯·诺依曼矫正、Hash提取)才能变成合格随机数。
国密安全规范与密钥生成流程
国密体系对密钥生成有明确规范,主要参考:
- GM/T 0005-2021 随机性检测规范
- GM/T 0028-2014 密码模块安全要求(类似FIPS 140-2 Level 3)
- GM/T 0091-2020 基于国密算法的随机数生成器设计指南
简单说,合规的密钥生成流程至少包含以下步骤:
- 熵源采集:硬件TRNG连续输出原始噪声,最小熵评估需达标。
- 去偏与后处理:使用SM3等算法对原始数据进行压缩提取,均匀化。
- 种子生成:由后处理输出安全种子(256bit以上),存入受保护存储区。
- DRBG实例化:基于种子,使用Hash_DRBG(SM3)或CTR_DRBG(SM4)生成随机数序列。
- 密钥导出:按算法需求截取或转换(SM2私钥需256bit,SM4密钥需128bit)。
- 在线自检:每次密钥生成后,随机抽样进行在线随机性检测。
下面是整个密钥生成流程的结构图:
随机数质量的在线检测实践
在产线上,你不能等随机数全部生成完再离线检测——成本太高。我通常的做法是:
- DRBG每输出1MB随机数,自动采样1024比特做在线游程检测和频数检测。
- 如果连续3次检测失败,模块进入故障安全模式,停止所有密钥生成服务。
- 同时记录日志并触发告警,方便运维人员排查熵源问题。
我建议至少采用 双级检测:第一级在TRNG输出端做实时最小熵评估(每10ms采样一次),第二级在DRBG输出端做统计检测。这样即使TRNG突发退化,也能在几毫秒内发现,避免生成大量弱密钥。
常见的坑与应对
问:能否直接用操作系统/dev/random给国密模块用?
答:合规要求必须使用符合GM/T 0091的硬件熵源+DRBG。系统随机数只适合作辅助输入,不能做主熵源。我在一次等保测评中亲眼看到某厂家直接拿/dev/urandom当种子被判定为不符合项。
另外一个容易被忽略的点:密钥生成过程中的旁路信息泄露。比如FPGA实现SM2密钥生成时,如果DRBG内部状态在时钟上可见,攻击者可以通过功耗分析获取种子。所以我设计时会把DRBG状态放在安全岛区域,用冗余逻辑加噪声填充。
总结几个硬原则
- 硬件熵源必须有国密认证,且支持自检。
- 后处理必须使用国密算法(SM3/SM4),不能自己写移位异或。
- 种子必须存储在防篡改区域(如安全芯片内部eFuse)。
- 在线随机性检测不能省略,且要有故障恢复机制。
- 所有检测数据和日志留存不少于6个月,便于追溯。
好吧,说白了一句话:密钥生成不是拍脑袋的事,熵源质量决定安全性,规范流程决定可靠性。做到这两点,你的密钥生命周期才算真正站住了脚。