WebTool

加密与安全系列 · 第 2 章

HMAC:给哈希加一把钥匙,让消息既防篡改又能验身份

WebTool 团队 · 发布于 2026-09-08 · HMAC / 签名 / 安全 / API

HMAC = 用密钥参与运算的哈希。裸哈希只能校验「数据是否损坏」,HMAC 还能证明「数据来自持钥者」——因此它是 API 接口签名的事实标准。 可以用本站 HMAC 计算工具动手验证。

为什么需要 HMAC

开放接口常要回答两个问题:

  1. 请求参数在传输中没被改过吗?(完整性)
  2. 请求真的是合法客户端发的吗?(真实性)

裸哈希 hash(params) 只能回答问题 1——攻击者改了参数后可以重新算一遍哈希。HMAC 把双方共享的密钥混入计算,攻击者没有密钥就造不出合法签名,两个问题同时解决。

为什么不能直接 hash(key + message)

这种朴素拼接存在长度扩展攻击:MD5/SHA-1/SHA-2 的 Merkle–Damgård 结构让攻击者在不知道 key 的情况下,可以在原文末尾追加数据并算出新的合法哈希。HMAC 的双层结构 H((k⊕opad) || H((k⊕ipad) || message)) 专门堵住了这条路。自己拼接密钥和消息是自造轮子的高危区,一律用标准 HMAC。

接口签名的标准姿势

stringToSign = method + "\n" + path + "\n" + sortedParams + "\n" + timestamp + "\n" + nonce
signature    = HexHMACSHA256(stringToSign, secretKey)
  • 参数排序后再参与签名,避免顺序差异导致验签失败。
  • timestamp 并校验时效(如 5 分钟),防截获后长期重放。
  • 加一次性 nonce 或请求 ID 防短时间重放。
  • 比较签名用常数时间比较,避免逐字节比较泄露时序信息。

常见误用

  • 把 HMAC 当加密:签名不隐藏内容,参数明文传输,机密性要靠 HTTPS。
  • 密钥硬编码进前端:浏览器里的密钥等于公开,前端签名方案必须另有设计(如临时凭证)。
  • 用 MD5/SHA-1 做 HMAC:虽然 HMAC 结构缓解了不少弱点,新系统仍应直接用 HMAC-SHA-256。

最后更新:2026-09-08