HMAC
HMAC 用共享 secret key 与 cryptographic hash 构造 Message Authentication Code,用来验证消息完整性与持有同一密钥的一方生成过该 MAC;它不提供 confidentiality,也不等于普通 hash。
[!info] related notes
HMAC
一句话定义
HMAC 是:
secret key + cryptographic hash → Message Authentication Code
它的目标是验证:
- message 没被未授权修改;
- MAC 由知道同一 secret key 的一方生成。
它不加密消息。
为什么普通 Hash 不够
普通 hash:
message
→ H(message)
任何人都可以重新计算。
攻击者如果能修改 message,也能同时重新计算 hash。
因此:
hash checksum 能检测偶然变化,但不能单独提供有 secret 的消息认证。
HMAC 加入只有通信双方知道的 secret key。
HMAC 的结构
抽象上:
HMAC(K, m) = H((K’ xor opad) || H((K’ xor ipad) || m))
工程上不需要手写该公式。
重要的是理解:
- outer hash;
- inner hash;
- shared key;
- underlying cryptographic hash。
这种标准构造避免了很多直接做 H(key || message) 的陷阱。
HMAC 与 Hash
| 能力 | Hash | HMAC |
|---|---|---|
| 需要 secret key | 否 | 是 |
| 完整性 fingerprint | 是 | 是 |
| 消息认证 | 否 | 是 |
| confidentiality | 否 | 否 |
| public verification | 否 | 否 |
HMAC 不是数字签名。
HMAC 与数字签名
HMAC:
- shared secret;
- 双方都能生成 MAC;
- 第三方无法仅凭 public key 验证,因为没有 public key。
Digital Signature:
- private/public key pair;
- private key holder 签名;
- public key holder 可验证。
因此 HMAC 不适合提供“只有 Alice 才可能生成”的公开可验证证据,因为 Bob 也掌握同一个 HMAC secret。
常见算法命名
例如:
- HMAC-SHA-256;
- HMAC-SHA-512。
HMAC 是 construction,SHA-256/SHA-512 是 underlying hash。
不要把它们当成两套完全独立机制。
Tag Truncation
某些 protocol 会截断 HMAC 输出。
截断 tag 不是简单“随便取前 N 位”。
tag length 会影响:
- forgery probability;
- protocol compatibility;
- security policy。
应按标准/protocol 规定使用,不要任意缩短。
Timing-Safe Comparison
验证 HMAC 时,不应在高安全要求场景用容易泄漏比较进度的普通逐字节早退比较。
应使用 platform 提供的 constant-time / timing-safe compare。
Secret Key Management
HMAC 安全性依赖 secret key:
- 足够随机;
- 不硬编码;
- 正确分发;
- 安全存储;
- 定期轮换;
- 不跨不相关用途复用。
如果所有客户端都内置同一 HMAC secret,那么逆向任一客户端可能泄漏全体密钥。
常见应用
- Webhook signature;
- API message authentication;
- token / protocol internal MAC;
- KDF/PRF construction;
- TLS / HKDF 内部构件。
具体 protocol 仍需明确:
- canonical message;
- timestamp;
- replay protection;
- key id/version。
Webhook 场景
一个稳健 webhook verification 往往需要:
timestamp + raw body
→ HMAC
→ compare tag
→ reject stale timestamp/replay
只验证 body 的 HMAC,不自动解决 replay attack。
标准状态
NIST FIPS 198-1 定义了 HMAC。
NIST 已提出将其内容迁移到 SP 800-224 并撤回 FIPS 198-1;这是文档体系更新,不代表 HMAC 这个 cryptographic construction 被淘汰。
学习检查
- 为什么普通 SHA-256(message) 不能替代 HMAC?
- HMAC 为什么不提供 confidentiality?
- HMAC 与 Digital Signature 的 key model 有什么差异?
- HMAC-SHA-256 中 HMAC 和 SHA-256 各自是什么角色?
- 为什么验证 tag 时应考虑 timing-safe comparison?
- 为什么 webhook 有 HMAC 后仍可能需要 timestamp / replay protection?
- 为什么把同一个 HMAC secret 内置到所有客户端风险很高?