0Pricing
Cryptology Academy · 课时

Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制

研究每种获 NIST 批准的 DRBG 机制的内部状态和输出生成过程。

Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制 是 CoddyKit 上的免费 Cryptology Academy 课时。 这是第 2 节课,共 4 节。 你可以在下方免费阅读本课时的完整内容 — 然后在浏览器中使用内置代码编辑器和全天候 AI 导师进行实践。 这是 Cryptology Academy 学习路径的一部分,你的进度在网页和 CoddyKit 应用中同步。 Cryptology Academy 课程共包含 4 节课。

DRBG 内部状态组件

三种 NIST DRBG 机制分别维护不同的内部状态组件,这反映了它们底层算法方法的差异。Hash_DRBG 保存 V(哈希长度的种子)和 C(由 V 派生、在生成输出时使用的常量)。HMAC_DRBG 保存密钥 K(哈希长度的秘密密钥)和值 V(哈希长度的链值)。CTR_DRBG 保存密钥 K(AES 密钥)和 V(块长度的计数器)。三者都会维护 reseed_counter,用于记录自上次播种以来的生成调用次数。状态大小决定内存占用:使用 SHA-256 的 Hash_DRBG 和 HMAC_DRBG 的状态大小为 64 字节;使用 AES-256 的 CTR_DRBG 使用 48 字节(32 字节密钥加 16 字节计数器)。

Hash_DRBG:Hash_df 派生函数

Hash_DRBG 使用 Hash_df(哈希派生函数)从熵材料派生状态。Hash_df(input_string, no_of_bits_to_return) 会进行迭代:对于 counter = 1, 2, ...,计算 H(counter || no_of_bits || input_string),并连接各次输出,直到产生足够的比特。该函数会将较短的熵输入扩展为足以容纳状态的种子。在 Generate 过程中,输出函数计算 W = H(0x03 || V),其中 0x03 前缀用于将此操作与其他哈希用途区分开来。输出循环为:data = H(0x01 || V);V = V + 1;需要更多输出时重复执行。生成完成后,更新 V:V = V + H(0x03 || V) + C + reseed_counter。通过前缀字节(0x01、0x03)进行域分离,可以防止将生成阶段的输出误认为状态更新阶段的输出。

HMAC_DRBG:Update 函数

HMAC_DRBG 的 Update 函数是所有状态转换的核心。Update(provided_data, K, V):K = HMAC(K, V || 0x00 || provided_data);V = HMAC(K, V)。如果 provided_data 不为空:K = HMAC(K, V || 0x01 || provided_data);V = HMAC(K, V)。这两步更新确保新密钥和值都依赖于之前的状态以及任何新熵。Generate 会循环执行 V = HMAC(K, V),并将结果追加到输出中,直到产生足够的比特;然后使用 additional_input 调用 Update,以推进状态。HMAC_DRBG 的安全性归结为 HMAC 是安全 PRF 这一假设:如果对手无法将 HMAC 输出与随机值区分开来,那么也无法将 DRBG 输出与随机值区分开来。

CTR_DRBG:Block_Cipher_df

CTR_DRBG 使用 Block_Cipher_df(派生函数)将种子材料处理为密钥和计数器格式。Block_Cipher_df(input_string, no_of_bits) 使用 BCC(分组密码链接)构造,对输入块反复执行 AES-CBC,以产生所需长度的输出。该派生函数对于处理可变长度的熵输入以及提供域分离都是必要的。不使用派生函数的 CTR_DRBG(允许在输入格式严格符合要求的 FIPS 测试中使用)速度更快,但对输入格式要求更敏感。Generate 循环为:temp = E(K, V);V = V + 1;将 temp 追加到输出中。Update:K || V = Block_Cipher_df(V || additional_input, seedlen);再与当前密钥执行 XOR。

DRBG 性能比较

不同类型的 DRBG 在性能上差异显著。在配备 AES-NI 的现代 x86_64 CPU 上,CTR_DRBG(AES-256)的伪随机输出速度约为 5–10 GB/s——AES-NI 指令使 AES 计算几乎不产生额外成本。HMAC_DRBG(SHA-256)的速度约为 200–400 MB/s——SHA-256 虽然很快,但硬件加速程度没有达到同样水平。Hash_DRBG(SHA-256)的速度约为 100–300 MB/s。对于批量密钥生成或替代流密码,CTR_DRBG 的速度明显更快。对于吞吐量较低的用途(会话密钥生成、随机数派生),性能差异并不重要。OpenSSL 3.0 因此将 CTR_DRBG(AES-256)作为默认机制。

实例化与个性化字符串

在实例化时,三种 DRBG 都接受可选的 personalization_string。该字符串会与熵输入混合,使 DRBG 实例具有唯一性。这样,即使两个同时实例化的 DRBG 获得相同的熵,也不会产生相同的输出,因为它们会根据个性化字符串产生分歧。建议使用的个性化字符串包括:应用程序标识符 + 进程 ID + 线程 ID + 时间戳 + 硬件标识符。即使两个 VM 获得了相同的熵(这是云 VM 快照导致的问题),不同的个性化字符串也能确保它们生成不同的 DRBG 数据流。NIST SP 800-90C 建议始终使用个性化字符串。随机数参数也有类似作用:它是一个唯一的短值,可确保没有两个实例化过程从相同状态开始。

Generate 调用中的附加输入

三种 DRBG 都支持在 Generate 调用中使用 additional_input 参数。调用方可以借此向单次生成调用注入额外的上下文或熵,而无需进行完整的重新播种。用途包括:(1) 注入来自辅助熵源的每请求熵;(2) 提供应用程序级上下文(请求 ID、时间戳),将生成值与其用途绑定;(3) 通过注入来自操作系统的新鲜熵,提供可选的预测抵抗性。additional_input 会在生成输出前混入 DRBG 状态。如果 additional_input 提供了真正的熵,就可以在无需正式重新播种的情况下提高安全性;正式重新播种需要使用熵源接口,并会产生相应的开销。

状态清零与密钥销毁

DRBG 取消实例化后(或切换到新实例时),必须安全地将内部状态清零。状态 V、C(Hash_DRBG)、K、V(HMAC_DRBG 和 CTR_DRBG)以及所有中间工作变量都必须用零覆盖。这称为显式清零,是 FIPS 140-3 模块的强制要求。在 C 代码中,应使用 explicit_bzero() 或 SecureZeroMemory()——编译器优化的 memset 可能会因无效存储优化而被移除,使密钥材料残留在内存中。Rust 的 zeroize crate 以及其他类似的语言专用方案可以以可移植的方式处理这一问题。在内存转储、冷启动攻击或进程检查工具可能暴露残留状态的场景中,安全销毁密钥十分重要。

DRBG 测试:CAVP 向量

NIST 为所有 SP 800-90A DRBG 提供密码算法验证计划(CAVP)测试向量。测试类型包括:(1) 已知答案测试——给定固定的熵输入、随机数和个性化字符串,验证生成的输出是否与预先计算的值匹配。(2) 重新播种测试——验证重新播种操作后的 DRBG 状态。(3) PR(预测抵抗性)测试——验证请求 prediction_resistance=true 后,在注入新鲜熵的情况下是否产生正确输出。提交 FIPS 140-3 认证申请时必须通过 CAVP 验证。开源库(OpenSSL、mbedTLS)会在其回归测试套件中包含 CAVP 测试向量,以发现 DRBG 实现中的回归问题。

DRBG 实现中的侧信道风险

除算法安全模型之外,DRBG 实现还面临细微的侧信道风险。对 AES 的缓存时序攻击(在不使用 AES-NI 的 CTR_DRBG 中)可能泄露轮密钥材料;AES-NI 通过在寄存器中计算且不进行查表,消除了这一风险。HMAC_DRBG 内部使用 HMAC;如果底层 SHA-256 采用恒定时间实现,HMAC_DRBG 也可以采用恒定时间实现。由于 SHA-256 没有依赖数据的分支,通常认为它本身是恒定时间的。针对生成 DRBG 的硬件进行的物理侧信道攻击(功耗分析、EM 辐射)是智能卡和物联网设备需要关注的问题,可以通过掩码实现来应对。状态备份攻击是指:如果对手能够通过内存泄露漏洞读取 DRBG 状态(类似 Heartbleed),那么在下一次使用新鲜熵重新播种之前,所有未来输出都会遭到破坏。

DRBG 状态泄露后的恢复

如果 DRBG 状态遭到泄露(例如通过内存泄露漏洞),恢复过程需要:(1) 检测泄露——DRBG 状态泄露不会自行显现,因此需要外部监控或完整性检查。(2) 使用来自可信来源的新鲜熵重新播种,并且该来源不能参与此次泄露。(3) 为所有从已泄露 DRBG 派生的密码材料重新换钥,包括自上次正常重新播种以来生成的会话密钥和签名密钥。(4) 对于软件实现,重启进程可以创建干净的 DRBG 实例。SP 800-90C 建议使用链式熵源——如果其中一个熵源遭到破坏,只要另一个熵源提供真正的熵,这种组合仍能提供安全性。

DRBG 状态测验

在现代 CPU 上,对于批量伪随机输出生成,哪种 DRBG 机制速度最快?

DRBG 内部机制总结

Hash_DRBG 使用迭代哈希和 Hash_df 进行派生,并通过 H(0x01 || V) 循环生成输出。HMAC_DRBG 使用 HMAC 作为 PRF,并通过两步式 Update 函数(先更新密钥,再更新值)实现简洁的安全性归约。CTR_DRBG 使用带 Block_Cipher_df 的 AES 计数器模式,在支持 AES-NI 的硬件上可达到 5–10 GB/s。三者都在实例化时接受 personalization_string,以确保实例唯一性;在每次生成时接受 additional_input,以绑定上下文。CAVP 测试向量用于验证实现。使用完毕后必须安全地将状态清零。状态遭到泄露后,需要使用新鲜熵重新播种,并为派生出的材料重新换钥。

常见问题解答

「Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制」课时是免费的吗?

是的 — 「Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制」的完整文本可在网页上免费阅读。要进行交互式练习(内置代码编辑器和全天候 AI 导师)并解锁 Cryptology Academy 课程的其余内容,请升级到 CoddyKit PRO。 Cryptology Academy 课程共包含 4 节课。

「Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制」这节课中我会学到什么?

研究每种获 NIST 批准的 DRBG 机制的内部状态和输出生成过程。 你通过在浏览器中直接运行的动手代码来练习 Cryptology Academy,全天候 AI 导师会在你学习这节课的过程中回答你的问题。

学习 Cryptology Academy 需要有经验吗?

无需任何先前经验。CoddyKit 上的 Cryptology Academy 课程适合初学者到高级学习者,你可以从这里开始或从头开始,按照自己的节奏学习。 这是第 2 节课,共 4 节。

「Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制」课时需要多长时间?

大多数 CoddyKit 课程大约需要 5–10 分钟。每节课都很精短且互动,所以你能稳步进步,并在网页和应用中从离开的地方继续。

我能在这节 Cryptology Academy 课中编写并运行代码吗?

能。每节 Cryptology Academy 课都包含内置代码编辑器,你可以在浏览器中直接编写并运行真实代码,并获得即时 AI 反馈 — 无需本地设置。

此课程中的所有课时

  1. NIST SP 800-90A:DRBG 标准
  2. Hash-DRBG、HMAC-DRBG 与 CTR-DRBG 内部机制
  3. Dual EC DRBG 后门事件
  4. 测试与验证 RNG 实现
← 返回 Cryptology Academy