首页 / 开发工具指南 / HMAC-SHA 指南

HMAC-SHA 算法完整指南

从 RFC 2104 到 API 签名:一文掌握 HMAC 的设计原理、7 个真实使用场景、与普通 SHA 哈希的差异、6 个实用技巧、以及数据安全与隐私建议。

📖 阅读时长约 11 分钟 📅 更新于 2026-06-20 ✍️ 土豆丝工具团队
🔐 立即试用 HMAC-SHA 计算工具
在线快速计算消息认证码,支持 HMAC-SHA1/256/384/512/SHA3/MD5,一次输入同时获得十六进制大小写与 Base64 三种输出,所有计算均在浏览器本地完成,保护您的密钥与数据隐私。
打开工具
#01

什么是 HMAC?理解消息认证码的设计目标

HMAC(Hash-based Message Authentication Code,基于哈希的消息认证码)是一种标准的消息认证码构造方法,由 IBM 的 Hugo Krawczyk 在 1996 年提出,1997 年发布为 RFC 2104

它同时实现了两个安全目标:

  • 数据完整性:消息在传输过程中被任何一方修改都会导致 HMAC 不匹配。
  • 发送方身份认证:只有持有预先约定密钥的一方,才能生成相同的认证码。

常见的误解是将 HMAC 等同于"带密钥的哈希"。但它的设计更为精巧:通过对密钥进行 ipad(0x36)与 opad(0x5C)两次填充,再分别与消息进行两次哈希,巧妙地回避了早期"key || message"简单拼接方案中存在的长度扩展攻击等风险。

我们的 HMAC-SHA 工具 中,只需输入消息与密钥即可直接生成标准认证码,无需理解填充细节。

#02

HMAC 的算法原理与常见哈希算法

HMAC 的核心公式如下(其中 H 代表哈希函数,如 SHA-256,K 为密钥,m 为消息,|| 表示字节拼接):

HMAC(K, m) = H((K ⊕ opad) || H((K ⊕ ipad) || m))

整个流程可以拆解为三个步骤:

  • 密钥处理:若密钥 K 长度大于哈希函数的分块大小(如 SHA-256 为 64 字节),先对 K 做一次哈希压缩;若小于分块大小,则在右侧补 0x00 到分块长度。
  • 内层哈希:将处理后的密钥与 ipad(每个字节为 0x36)进行异或,再拼接消息 m,计算一次哈希得到内层摘要。
  • 外层哈希:将处理后的密钥与 opad(每个字节为 0x5C)进行异或,再拼接下来层摘要,做一次外层哈希,最终得到 HMAC。

由于哈希函数是可替换的,HMAC 自然支持多种算法:

  • HMAC-SHA1:输出 40 位十六进制字符(160 位),兼容旧系统,但碰撞强度已不足。
  • HMAC-SHA256:输出 64 位十六进制字符(256 位),是当前业界最通用的选择,也是 JWT 默认算法 HS256 的基础。
  • HMAC-SHA384 / HMAC-SHA512:输出 96 / 128 位十六进制字符,提供更长摘要与更高安全余量,适合对安全性要求苛刻的系统。
  • HMAC-SHA3-256 / HMAC-SHA3-512:基于 Keccak 海绵结构,与 SHA-2 代数结构不同,用于需要"算法多样性"的场景。
  • HMAC-MD5:输出 32 位十六进制字符,仅应在向后兼容与非安全场景使用。

我们的工具 中,可在同一界面切换上述 7 种算法,快速对比不同算法下的输出差异。

#03

常见输出格式:十六进制大小写与 Base64

HMAC 的原始输出是固定长度的二进制字节数组。在实际工程中,通常以以下 3 种可打印格式传递:

  • 十六进制小写:每个字节表示为两位小写十六进制字符(如 f7bc83f4…)。这是最通用的默认格式,Node.js 的 crypto.createHmac().digest("hex")、Python 的 hmac.new().hexdigest()openssl dgst -sha256 -hmac 等默认以小写输出。
  • 十六进制大写:与小写内容完全相同,仅以大写字符呈现。常见于 Java 的 javax.xml.bind.DatatypeConverter、某些 .NET API、以及一些传统接口规范中。直接字符串比对大小写不同的 HMAC 会失败,尽管数值相同。
  • Base64 编码:对原始字节数组做 Base64 编码,输出更紧凑(SHA-256 对应 44 字符),广泛用于 JWT 签名、OAuth 1.0a、AWS Signature v4、以及 HTTP 请求签名等场景。

一个常见的调试陷阱是"服务端以 Base64 输出,客户端以十六进制进行比对",或反之。将两者转换到同一表示形式是排障的第一步。我们的工具一次输入同时提供三种输出,可直接与您的服务器实现对比。

#04

7 个真实使用场景:什么时候使用 HMAC?

HMAC 几乎出现在每一个涉及"身份+完整性"的系统中。以下是 7 个典型真实场景:

  • REST API 请求签名:客户端将请求参数、时间戳、随机字符串连同密钥一起做 HMAC-SHA256,服务端以相同方式重放比对,防止中间人篡改。
  • Webhook 回调验证:GitHub、Stripe、Slack、钉钉等平台会在回调请求头中携带 X-Hub-Signature-256 / stripe-signature 等 HMAC 摘要,接收方以此确认事件确实来自原始平台。
  • JWT 签名算法 HS256 / HS384 / HS512:JSON Web Token 的 HMAC 族算法,使用共享密钥对 Header.Payload 进行签名,接收方以相同密钥校验。
  • OAuth 1.0a 签名:在较老的 OAuth 1.0a 规范中,HMAC-SHA1 是最常见的签名方法,用于对请求参数进行认证。
  • AWS Signature v4 / 阿里云 API 签名:云厂商的请求签名机制通常使用 HMAC-SHA256 对规范化请求字符串与日期进行多层签名,以验证请求者身份。
  • 下载文件完整性校验(带密钥):在对安全性要求更高的分发系统中,服务端可对每个文件生成 HMAC,接收方用预共享密钥验证,比公开的 SHA 校验多一层身份保护。
  • 一次性口令 / CSRF Token:在 CSRF Token、One-Time Password、短链接签名等场景中,用 HMAC 将时间或序号与密钥绑定,避免被伪造。

在上述场景中,使用 在线 HMAC-SHA 工具 进行本地复现,可以快速判断"是客户端计算错了,还是服务端校验错了",大幅缩短接口联调时间。

#05

HMAC vs 普通 SHA vs JWT:如何选择合适的认证方案

理解不同方案的差异能让您在架构决策时做出正确选择:

  • 普通 SHA 哈希:仅保证数据完整性,不提供身份认证。任何人都能计算相同哈希,适合公开文件校验。
  • HMAC-SHA:同时提供完整性与身份认证,基于共享对称密钥。适合服务器之间、API 调用、Webhook 等有预共享密钥的场景。
  • JWT(HS256/HS384/HS512):实际上就是 HMAC-SHA,只是将消息规范化为 base64url(header).base64url(payload) 形式,签名再以 Base64URL 附加。方便携带结构化声明。
  • JWT(RS256/ES256 等非对称签名):使用私钥签名、公钥验证,避免密钥在多方共享泄露风险。适合多租户、OAuth2 等开放系统。
  • AES-GCM 等带认证的加密:当不仅要认证,还要加密消息时,使用 AEAD(带关联数据的认证加密)方案,如 AES-GCM、ChaCha20-Poly1305。

经验法则:若两方已有共享密钥并且消息是明文传输 → 使用 HMAC-SHA256;若消息需要携带可被第三方验证的声明 → 使用 JWT(HS256 或 RS256);若需要"签名者与验证者使用不同密钥" → 使用非对称签名;若还要保证消息不可被他人读取 → 使用 AEAD 加密。

如需验证普通 SHA 哈希的计算是否正确,可在 SHA 工具 中对比;若需要 HMAC 的结果,则使用 HMAC-SHA 工具

#06

6 个实用技巧:避免签名调试陷阱

HMAC 的公式虽简单,但在实际联调中经常因微小差异导致签名失败。以下是 6 条实用排障技巧:

  • 统一字符编码:HMAC 是对字节进行运算的。同一字符串在 UTF-8、UTF-16、GBK 下字节序列不同,HMAC 必然不同。务必统一使用 UTF-8 编码。
  • 统一换行符与空白处理:多行消息在 Windows 中是 ,在 Linux / macOS 中是 。若客户端与服务端对换行符处理不同,HMAC 将不一致。
  • 规范化参数顺序:API 签名通常要求参数按键名排序后再拼接。请严格遵循相同排序规则,避免大小写敏感的参数名差异。
  • 十六进制 vs Base64:选择一致的输出格式:若文档要求返回 Base64,请不要将十六进制字符串直接返回;反之亦然。可用 我们的工具同时输出两种格式对比。
  • 密钥是否需要先做哈希或解码?:部分平台要求密钥先做 Base64 解码再用于 HMAC,而有些平台直接使用字符串字节。请严格阅读文档确认。
  • 时间戳、随机串、重放保护:签名中通常包含时间戳与随机字符串。时间差过大、时间戳单位(秒 vs 毫秒)不同,都会导致失败。排障时,建议先写死一个固定时间戳与固定随机串,验证基础算法是否一致。

将这些步骤写入团队的接口联调 Checklist,可以显著减少"为什么签名总是不对"的调试时间。

#07

数据安全与隐私:为什么本地处理的在线工具更安全

当您需要计算一个涉及密钥(如生产环境 API Secret)的 HMAC 时,请务必警惕"看起来便利"的在线工具。关键问题在于:该工具是否将您的密钥上传到服务器?是否会记录请求?

我们的 HMAC-SHA 工具基于浏览器内置的 Web Crypto API 与 CryptoJS 实现,所有计算完全发生在您的浏览器中,HTTP 层面不存在任何与密钥或消息相关的上传请求,也不会将输入内容写入 localStorage

尽管如此,以下是几条额外的安全建议:

  • 处理敏感密钥时使用隐私浏览模式:关闭窗口后不会在浏览器历史、自动填充或扩展中留下痕迹。
  • 不要在公共或公司监控设备上输入生产密钥:键盘记录器与屏幕录制可能绕过浏览器层安全保护。
  • 避免将真实密钥写入公开文档或 Git 仓库:即便用于调试,也请使用临时测试密钥。
  • 定期轮换密钥:一旦怀疑密钥可能泄露,应立即在服务端进行轮换。
  • 绝不要用裸 SHA 替代 HMAC 做身份认证:SHA 只保证完整性,不保证来源;HMAC 才同时提供两者。

选择 一个本地处理、无日志、无上传的在线 HMAC 工具,可以在不牺牲便利的前提下牢牢掌握自己的密钥控制权。