Skip to content

算法Algorithm

HMAC的内外层密钥哈希

HMAC · Hash-based message authentication code

从密钥归一化和内外pad写出HMAC字节接口,复算标准向量,并区分MAC安全、PRF假设与裸前缀哈希。

形式陈述 ​

HMAC是使用密码哈希构造消息认证码的具体算法。设底层哈希输出 h 字节、压缩块长 B 字节,并假定 h≤B(SHA-256满足此条件)。先将密钥 K 归一化:若 |K|>B,以 H(K) 替代;随后右补零至恰好 B 字节,得 K0。定义

HMACK(m)=H((K0⊕opad)‖H((K0⊕ipad)‖m)).

ipad 是 B 个 36 十六进制字节,opad 是 B 个 5c 字节。SHA-256实例中 B=64,h=32,不能把32字节摘要长度误作64字节块长。验证重新计算标签并使用适合的恒定时间标签比较接口比较全部约定字节;普通逐字节比较若遇错提前退出,会泄漏匹配前缀,见泄漏轨迹模型。专门比较接口也不等于整个程序已通过常数时间验证。若采用截断,截断长度与规则必须双方预先固定。

这条公式定义算法,不独立证明安全。作为MAC,需要相应的不可伪造结论;用于HKDF或密钥扩展时,通常还需要PRF性质。两项主张与底层压缩函数的假设、查询范围和具体分析有关。仅有“哈希抗碰撞”不能机械推出这里需要的全部PRF保证。

直觉

内层把密钥混入消息处理,外层再用不同pad把内部摘要封住。攻击者拿到的是外层输出,不能像某些Merkle–Damgård裸前缀哈希那样,把暴露的链值继续扩展成合法新消息标签。

内外pad是构造规定的一部分,不是两把可随意选用的独立密钥;把它们设相同、删除一层或调整填充,都变成另一个需要重做分析的算法。现实应用应调用可信库,手写公式主要用于理解和标准向量核对。

例子与边界

RFC4231测试1使用20字节 0b 作为密钥、ASCII字符串 Hi There 作为消息。HMAC-SHA256完整32字节结果为

b0344c61d8db38535ca8afceaf0bf12b881dc200c9833da726e9376c2e32cff7。

可以逐层复算:先把20字节密钥补44个零;分别与64字节ipad、opad异或;内层哈希输入长为64+8=72字节;外层输入长为64+32=96字节。这里是传入哈希的长度,不含SHA-256内部自行添加的填充。

若密钥是100字节,先哈希得到32字节,再补32个零;不能直接截成64字节。HMAC的密钥归一化也意味着不同原始密钥可能得到同一 K0,例如短密钥后添零在一定长度内不改变归一化结果。因此“密钥字节不同”不等于统计独立密钥,应用应采用规定的随机密钥生成与用途派生。

HMAC不隐藏消息,也不自动拒绝旧消息。收到一份旧的合法标签再验一次仍会通过,协议需要自己的接收状态。使用短标签时,理想 t bit标签的单次盲猜成功率是 2−t,多次在线尝试还要计查询预算;不能用摘要算法名掩盖实际只比较了4字节。

推论与应用

HMAC把既有MAC抽象落到一个可互操作的字节算法,但旧MAC页中的EUF-CMA、强新鲜性和PRF归约仍是安全接口的主定义。HMAC的内外层结构不能被当成任意组合协议的认证证明。

检查器通过Python标准库计算RFC4231已公布向量,再用同一HMAC实现HKDF。两个输出一致支持实现符合这些测试输入;它不测试底层机器的侧信道,也不证明所有消息长度或所有平台的实现都正确。

若底层哈希每块成本固定,消息m字节、原密钥k字节,计算成本为 O(⌈m/B⌉+⌈k/B⌉+1) 次块处理;短密钥不需先哈希。流式实现除输入和输出外可用 O(B+h) 工作空间,长消息不必全部驻留。固定密钥下可安全复用库规定的内外初始状态优化,但不能复用上一条消息的最终链值。

参考资料
  • Hugo Krawczyk、Mihir Bellare、Ran Canetti,RFC 2104,§2:密钥归一化、pad和HMAC构造;§5:截断
  • M. Nystrom,RFC 4231,§4.2测试1:HMAC-SHA256向量
  • Dan Boneh、Victor Shoup,A Graduate Course in Applied Cryptography, v0.6,§8.7,特别是§§8.7.1–8.7.2:two-key nest分析与HMAC标准之间的假设桥梁
关系图谱8 个相邻概念 · 2 类关系

拖动节点调整位置。

显示关系

显示:依赖

  1. 前置三跳
  2. 前置二跳
  3. 前置一跳
  4. 当前条目
  5. 后续一跳
  6. 后续二跳
  7. 后续三跳
文字版关系按与当前条目的最短距离分组
类型化关系

使用的工具