3. 后量子密钥的生成要求与熵源管理

后量子密码(PQC)算法在数学结构上比 RSA/ECC 更复杂,密钥尺寸也更大,但这并不意味着密钥生成可以“随便调用一个随机函数”。恰恰相反,PQC 密钥的安全性对随机数质量更为敏感:ML-KEM 的种子、ML-DSA 的私钥多项式系数、SLH-DSA 的密钥种子,全部由随机比特直接决定。一旦熵源存在偏差或可预测性,攻击者无需破解格问题,就能直接重建私钥。本节围绕三个相互衔接的环节展开:合规随机数生成器的选择、密钥生成参数的正确设定、弱密钥的检测与规避。

一、熵源与 DRBG:合规链条从物理熵开始

NIST SP 800-90 系列把随机性来源分成三层:物理熵源(熵源,Entropy Source)、条件化组件(Conditioning Component)和确定性随机比特生成器(DRBG)。SP 800-90B 规范的是熵源与条件化部分,要求熵源经过健康测试(Health Tests),并对其输出给出保守的熵估计;SP 800-90A 规范 DRBG 的构造,如 Hash_DRBG、HMAC_DRBG、CTR_DRBG。合规的密钥生成路径应当是:物理熵源 → 条件化 → 种子 → DRBG → 密钥生成算法,每一层都有明确的接口与验证要求。

工程上最常见的误区是“熵源看起来能用就行”。SP 800-90B 要求熵源持续运行启动健康测试(如上电时的重复计数测试、自适应比例测试)和连续健康测试,一旦测试失败必须立即报错并停止输出,而不是静默降级。另一个误区是把 DRBG 的种子长度等同于熵。以 CTR_DRBG(AES-256)为例,其种子材料需要 384 比特(密钥 256 比特 + V 值 128 比特),但真正注入的熵至少应达到安全强度要求,例如 256 比特。种子中的其余部分可以由 DRBG 内部派生,但不能反过来把“种子长度”当作“熵含量”。

PQC 密钥生成:熵源合规链与弱密钥检测回路 物理熵源 环形振荡器/噪声源 SP 800-90B 健康测试 条件化组件 去偏、压缩、熵估计 输出 ≥ 256 bit 熵 DRBG CTR_DRBG(AES-256) 种子 384 bit / 熵 256 bit 密钥生成算法 ML-KEM / ML-DSA SLH-DSA 种子派生 弱密钥检测 自检 / 拒绝采样 失败即丢弃重生成 检测不通过:丢弃并重新取随机数 密钥生成参数选择要点 • 安全等级:ML-KEM-768 / ML-DSA-65 对应 NIST 3 类 • 种子来源:必须来自合规 DRBG,禁止硬编码或时间戳 • 随机字节数:按算法规范精确取用,不多取不漏取 • 拒绝采样:系数越界时重取,不得取模截断 • 上下文绑定:绑定算法标识与用途,防止跨用途复用 典型弱密钥与规避手段 低熵种子 规避:熵源健康测试 + 熵估计 系数分布偏斜 规避:严格拒绝采样,不取模 种子复用/重放 规避:每次生成唯一上下文 实现侧信道泄漏 规避:常数时间采样与自检

二、密钥生成参数:按规范精确取用随机字节

PQC 算法的密钥生成接口通常接受一个固定长度的随机种子,再由算法内部展开。以 ML-KEM 为例,其密钥生成需要 32 字节的随机种子 d 和 32 字节的 z(用于隐式拒绝),合计 64 字节;ML-DSA 的密钥生成需要 32 字节种子 ξ,再通过 SHAKE-256 派生出 ρ、ρ′、K。这些长度是算法规范的一部分,实现时必须精确取用,不能“多取一点更安全”,也不能“少取一点省事”。多取会破坏与标准测试向量的互操作性,少取则直接降低熵含量。

更关键的是采样环节。ML-KEM 和 ML-DSA 的私钥多项式系数需要服从特定的分布(如中心二项分布或均匀分布),实现方式是从 DRBG 取随机字节后做拒绝采样:若采样值落在有效区间外,则丢弃并重新取,直到得到合法系数。这里有一个经典错误——用取模运算把越界值“压”回区间内。取模会引入分布偏斜,使某些系数出现概率偏高,攻击者可以利用这种偏斜做统计区分攻击,逐步恢复私钥信息。正确做法是严格拒绝采样,宁可多消耗随机字节,也不破坏分布。

参数选择还应考虑安全等级与性能的平衡。NIST 将 PQC 算法分为 1、3、5 类安全等级,分别对应约 AES-128、AES-192、AES-256 的强度。ML-KEM-768 和 ML-DSA-65 属于 3 类,是当前推荐的通用选择;对高价值长期密钥可选用 5 类(ML-KEM-1024、ML-DSA-87),但公钥和签名尺寸会显著增大。选择时应结合密钥用途、存储周期和带宽约束,而不是一律取最高等级。

三、弱密钥检测与规避:把检测做进生成流程

弱密钥检测不是生成之后的“抽查”,而应嵌入生成流程本身。第一层是熵源健康测试:上电时执行重复计数测试,运行中执行自适应比例测试,任何失败都触发告警并阻止密钥输出。第二层是 DRBG 自检:在实例化、重新播种和生成前后执行已知答案测试(KAT),确认 DRBG 输出与预期一致。第三层是算法级自检:用固定种子生成密钥对,与标准测试向量比对,确认采样、编码、序列化各环节正确。

对于“弱密钥”本身,需要区分两类情况。一类是随机性缺陷导致的低熵密钥,例如种子被截断、DRBG 未正确播种、虚拟机快照导致种子重复。这类问题无法从单个密钥的外观判断,只能靠熵源测试和种子唯一性审计来发现。另一类是算法实现导致的分布异常,例如拒绝采样写错、系数编码越界、模数约简错误。这类问题可以通过统计检验发现:对大量生成的密钥系数做频数分布检验,观察是否符合理论分布;对种子做重复性检测,确认没有重复种子。

常见陷阱:在容器或虚拟机中,若熵池尚未初始化就调用密钥生成,可能拿到低质量随机数。应在启动流程中显式等待熵池就绪(如读取 /proc/sys/kernel/random/entropy_avail 达到阈值),或使用经过认证的硬件随机数发生器。另一个陷阱是把 DRBG 的“重新播种”当作可选操作——长期运行的 DRBG 必须按规范周期重新播种,否则输出序列的可预测性会随时间累积。

四、一个可执行的生成与检测流程示例

下面给出一个教学示例流程(参数为示例值,非实测结果),展示从熵源到密钥落地的完整闭环。假设使用 CTR_DRBG(AES-256),安全目标为 3 类,生成 ML-KEM-768 密钥对:

1. 熵源就绪检查:entropy_avail ≥ 256 bit,健康测试通过
2. DRBG 实例化:注入 256 bit 熵 + 非机密个性化串(算法标识 "ML-KEM-768")
3. 取随机种子:读取 64 字节(d 32B + z 32B),记录种子指纹用于唯一性审计
4. 算法内部展开:SHAKE-256 派生 ρ、σ,拒绝采样生成矩阵 A 与向量 s、e
5. 自检比对:用固定种子跑 KAT,输出与标准向量逐字节一致
6. 弱密钥筛查:种子指纹查重(应无重复);系数分布频数检验在容差内
7. 通过则封装密钥对并写入密钥库;任一步失败则丢弃全部中间值并重新生成

这个流程的关键在于“失败即丢弃”:一旦健康测试、KAT 或分布检验任一环节不通过,不能只重试失败的那一步,而应丢弃本次生成的全部中间材料,从熵源重新开始。原因是失败可能意味着熵源已被污染或 DRBG 状态已不可信,局部重试无法排除污染。同时,种子指纹(如对种子做 SHA-256 后的前 16 字节)应写入审计日志,用于事后排查种子重复问题,但指纹本身不能泄露种子内容。

最后需要强调,PQC 密钥生成的安全性并不来自算法名字,而来自“熵源合规、参数精确、检测嵌入”这三件事同时成立。任何一环被简化,都会让后量子算法在面对实现层攻击时失去意义。把 SP 800-90B 的健康测试、SP 800-90A 的 DRBG 规范和算法自身的采样要求串成一条可验证的链条,才是后量子密钥生命周期管理的正确起点。