HMAC 生成器与签名校验工具
免费在线 HMAC 生成与校验工具。支持文本、Hex 或 Base64 密钥计算 HMAC-SHA256/SHA1/SHA384/SHA512,输出 Hex/Base64/Base64URL。100% 在浏览器中运行 —— 密钥永不离开页面。
什么是 HMAC?
HMAC(基于哈希的消息认证码)是一个短小的定长标签,用来证明一条消息既未被修改又是真实的 —— 即由持有共享密钥的人产生。HMAC 在 RFC 2104 和 FIPS 198-1 中定义,它把任意密码哈希函数与一个密钥按特定嵌套结构组合,写作 HMAC(K, m) = H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ m))。内层哈希把密钥绑定到消息上;外层哈希包裹结果,正是这一点使 HMAC 能抵抗影响裸 SHA-1 和 SHA-256 函数的长度扩展攻击。
HMAC 遍布现代 Web 基础设施。它为 webhook 签名,让你能确认一个传入请求确实来自 GitHub、Stripe、Slack 或 Twilio 而非伪造。它为 API 请求签名(AWS Signature Version 4 就建立在 HMAC-SHA256 之上),让服务器无需在链路上发送密码即可认证调用方。它是 HS256 里的那个 S:用 HS256 签名的 JWT 会对其头部和载荷携带一个 HMAC-SHA256,你可以用 JWT 编码器查看。它还支撑着 TLS 密钥派生(HKDF)、一次性密码算法(HOTP/TOTP),以及无数内部服务的消息完整性。
本工具完全在你的浏览器中、用 Web Crypto API 的 crypto.subtle.sign('HMAC', ...) 计算 HMAC —— 这正是浏览器在 TLS 握手时使用的同一个原语。你的密钥和消息绝不会被上传,因此用于生产签名密钥也安全。由于同一个密钥可以表示为原始文本、hex 或 base64,工具让你显式选择「密钥编码」;又因为不同服务商期望不同形式的标签,你可以输出 Hex、Base64 或 Base64URL。「校验」标签页让你检查收到的签名,并使用常量时间比较,让检查本身不泄露时序信息。
const crypto = require('crypto');
// HMAC-SHA256 with a UTF-8 text key, hex output
const hmac = crypto
.createHmac('sha256', 'my-secret-key')
.update('Hello, World!')
.digest('hex');
console.log(hmac);
// → 'cf3141611e22ea26a9cac6fe41d941274dd6653622c83cba13972d177bd69699'
// Verify a signature in constant time
function verify(message, key, expectedHex) {
const actual = crypto.createHmac('sha256', key).update(message).digest();
const expected = Buffer.from(expectedHex, 'hex');
return actual.length === expected.length &&
crypto.timingSafeEqual(actual, expected);
} 核心特性
生成与校验合于一处
在「生成」标签页生成签名,或在「校验」标签页粘贴「预期 HMAC」来认证传入的 webhook 或令牌。校验使用常量时间比较,因此结果绝不泄露时序信息。
可选密钥编码
将你的密钥解释为 Text(UTF-8)、十六进制或 Base64。这是大多数其他工具会省略的设置 —— 也是两个系统对同一密钥算出不同 HMAC 的最常见原因。
三种输出编码
把标签输出为 Hex(GitHub webhook、AWS)、Base64(Stripe、Twilio、许多 API)或 Base64URL(JWT 和 URL 安全令牌),无需手动转换即可匹配你的集成。
四种原生算法
默认 HMAC-SHA256,另有 SHA-1、SHA-384 和 SHA-512。全部运行于浏览器的 Web Crypto API,因此无需信任任何 JavaScript 加密库,也没有性能损失。
100% 客户端且私密
你的密钥和消息完全在浏览器中处理,绝不发送到任何服务器。打开网络面板,你会看到零次外发请求 —— 用于生产签名密钥也安全。
实时计算
当你编辑消息、密钥、编码或算法时,HMAC 会即时重算 —— 无需点「生成」按钮往返,让你可以反复试不同编码,直到你的值与服务器一致。
基于已验证的测试向量
输出经官方 RFC 4231 HMAC 测试向量验证,因此你可以信任这些摘要与 OpenSSL、Node 的 crypto 模块以及 Python 的 hmac 库产出的结果一致。
HMAC 示例
快速上手 —— HMAC-SHA256,Hex 输出
Hello, World!
cf3141611e22ea26a9cac6fe41d941274dd6653622c83cba13972d177bd69699
使用密钥 "my-secret-key"(密钥编码 = Text)、算法 HMAC-SHA256、输出格式 = Hex 时,消息 "Hello, World!" 生成 cf3141611e22ea26a9cac6fe41d941274dd6653622c83cba13972d177bd69699。这正是 Node 的 crypto.createHmac('sha256', key).update(msg).digest('hex') 给出的标准 64 字符十六进制摘要。
校验 Stripe 风格 webhook(Base64 输出)
{"id":42,"event":"user.created"} Cd2f7zTKaJFeG6k+t1FcvDPn51OAZ2f4GrxkCUgMhGs=
许多 webhook 服务商以 Base64 形式发送签名。使用密钥 "whsec_test_secret"(Text)、HMAC-SHA256、输出格式 = Base64 时,该 JSON 体签名得到 Cd2f7zTKaJFeG6k+t1FcvDPn51OAZ2f4GrxkCUgMhGs=。把该值粘到「校验」标签页,在处理请求前确认它确实来自你的服务商。HMAC 在内部运行的底层原语与我们的 SHA-256 哈希生成器相同,只是用你的密钥做了加密。
RFC 4231 参考向量
what do ya want for nothing?
5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
这是 RFC 4231(官方 HMAC 测试向量文档)中的测试用例 2。使用密钥 "Jefe"(Text)、HMAC-SHA256、Hex 输出时,消息 "what do ya want for nothing?" 得到 5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843。能匹配这个精确值,就证明你的 HMAC 实现是正确的。
HMAC-SHA512 生成更长摘要
The quick brown fox
36f44b125a8a90639dc46733039571792e081e0fd8685ff746784b02ed14aa35629d562c7117cde4a701570551faa5a5e1b7ef1eb5c3bcd4cc1fdb8923fcf14e
把算法切到 HMAC-SHA512 可得到 128 字符(512 位)摘要。使用密钥 "key"(Text)和 Hex 输出时,"The quick brown fox" 生成上面的值。SHA-512 在多数 64 位硬件上比 SHA-256 更快,输出也更长,不过 SHA-256 仍是互操作的默认选择。
如何生成与校验 HMAC
- 1
选择算法
选 HMAC-SHA256(默认值,也几乎适用于所有 webhook、API 和 JWT),或切到 SHA-1、SHA-384、SHA-512 以匹配某个要求它的系统。这四种都通过 Web Crypto API 在你的浏览器中原生运行。
- 2
输入密钥并设置其编码
键入或粘贴你的密钥,然后把「密钥编码」设为与服务器解释方式一致:普通字符串用 Text(UTF-8),十六进制数据用 Hex,base64 密钥用 Base64。设错这一项是 HMAC 不匹配的头号原因,拿不准时三种都试一遍。
- 3
输入消息
粘贴你想签名的确切字节 —— 对 webhook 而言就是逐字节的原始请求体,不做任何重新序列化或空白改动。HMAC 会随你的编辑实时重算,不会向任何服务器发送数据。
- 4
选择输出格式并复制
选择 Hex(GitHub 风格)、Base64(Stripe/AWS 风格)或 Base64URL(JWT 风格)以匹配你的集成所需,然后点击「复制」获取签名。
- 5
校验已有签名
切到「校验」标签页,粘贴来自请求头或令牌的「预期 HMAC」,工具会以常量时间确认你计算的签名是否匹配 —— 这样你就能在对载荷采取行动前先认证它。
常见 HMAC 错误
密钥编码不匹配(不匹配的头号原因)
同一个密钥可以被读作原始 UTF-8 文本、hex 或 base64 —— 每种解释都会产生完全不同的密钥字节,因此一旦你的工具和服务器解释不一致,HMAC 就会对不上。如果服务商给你一个 hex 或 base64 密钥,你必须先把它解码为字节再签名,而不能照字符串原样签。当签名校验失败时,先用三种「密钥编码」选项都试一遍。
// Server stored a base64 secret but you sign the literal string
createHmac('sha256', 'c2VjcmV0LWtleQ==').update(msg) // Decode the base64 secret to raw bytes first
createHmac('sha256', Buffer.from('c2VjcmV0LWtleQ==', 'base64')).update(msg) 输出编码不匹配
HMAC 是原始字节;hex、base64 和 base64url 只是同一值的不同文本编码。如果服务器发来一个 base64 签名,而你拿它和你的 hex 摘要比,即便底层字节完全相同它们也永远不会匹配。把「输出格式」与请求头或令牌所用的对齐。
// Provider sends base64, you compare hex
expected = 'Cd2f7z...=' // base64
actual = digest('hex') // hex — never matches // Produce the same encoding the provider uses
actual = digest('base64') 对重新序列化的 JSON 而非原始体签名
Webhook 签名覆盖的是服务商发来的确切字节。如果你解析 JSON 再重新字符串化,键顺序、间距和数字格式都可能改变,从而改变字节并破坏签名。永远对解析前捕获的原始请求体做 HMAC。
// Re-serialization changes the bytes body = JSON.stringify(JSON.parse(rawBody)) verify(hmac(body))
// Sign the raw bytes exactly as received verify(hmac(rawBody))
用 == 而非常量时间比较
用 == 或简单字符串相等来比较收到的签名会泄露时序信息,因为比较会在第一个不同字节处停止。经过多次尝试,攻击者可恢复出有效标签。校验时务必使用常量时间相等检查。
if (received === computed) { /* trust */ } if (crypto.timingSafeEqual(receivedBuf, computedBuf)) { /* trust */ } HMAC 用于什么
- 校验 webhook 签名
- GitHub、Stripe、Slack、Twilio 等服务商会用只与你共享的密钥对请求体做 HMAC 来签每个 webhook。重算标签并与请求头(例如 X-Hub-Signature-256)比较,在采取行动前确认事件是真实的。用「校验」标签页即可完成,无需写一次性代码。
- 为 API 请求签名
- 经过认证的 API 常要求客户端用共享密钥对请求(方法、路径、时间戳、请求体)做 HMAC 签名,而不是直接发送密钥本身。AWS Signature Version 4 是典型例子。本工具让你逐步复现并调试这些签名。
- 保证消息完整性
- 当你在服务之间传递令牌、cookie 或消息时,附上一个 HMAC 能让接收方检测出任何篡改。由于标签依赖于密钥,攻击者在修改数据后无法重算它 —— 这与普通校验和不同。
- 理解 JWT HS256 签名
- 用 HS256 签名的 JWT 就是 base64url(header) + '.' + base64url(payload),用 HMAC-SHA256 签名并把结果以 Base64URL 输出。把算法设为 SHA-256、输出设为 Base64URL,就能看到该签名究竟是如何产生的,再到 JWT 编码器中交叉核对。
- 调试对不上的签名
- 当你的 HMAC 与服务器对不上时,本工具是定位原因的最快途径:把密钥分别当作 Text、Hex、Base64 试,把输出在 Hex 和 Base64 之间切换,并确认你签的是确切的原始字节 —— 全程无需重新部署任何代码。
HMAC 工作原理
- RFC 2104 结构
- HMAC 定义为 H((K ⊕ opad) ‖ H((K ⊕ ipad) ‖ m)),其中 ipad 是重复的字节 0x36,opad 是重复的 0x5c,两者都补到哈希的块大小。长于块大小的密钥会先被哈希;短于块大小的密钥则用零填充。正是这种两遍嵌套赋予 HMAC 其安全性证明,即便底层哈希不抗碰撞,该证明依然成立。
- 为何带密钥的哈希胜过普通哈希
- 普通哈希只能证明数据未被意外损坏,因为任何人都能为任意消息(包括被篡改的)重算它。HMAC 混入了一个密钥,因此只有密钥持有者才能产生有效标签。这把「仅完整性」转变为「完整性加真实性」,而这正是 webhook 和签名请求真正需要的性质。
- 抵抗长度扩展
- 裸 SHA-1、SHA-256 和 SHA-512 是 Merkle–Damgård 哈希,易受长度扩展攻击:给定 H(secret ‖ msg),攻击者无需知道密钥即可计算 H(secret ‖ msg ‖ extra)。朴素的「密钥前缀 MAC」方案因此被攻破。HMAC 的外层哈希中和了该攻击,这是用 HMAC 而非把密钥和消息哈希到一起的主要原因。
- 在 SHA-256 与 SHA-512 之间选择
- HMAC-SHA256 产生 256 位(64 个 hex 字符)标签,是互操作的默认值 —— 快速、普及、处处支持。HMAC-SHA512 产生 512 位(128 个 hex 字符)标签,在 64 位 CPU 上往往更快,因为 SHA-512 用 64 位字。除非规范或对端系统要求 SHA-512,否则选 SHA-256;两者用于认证都安全。
- Web Crypto 实现
- 本工具调用 crypto.subtle.importKey 加载你的密钥(从 Text、Hex 或 Base64 解码),并用 crypto.subtle.sign('HMAC', ...) 计算标签,再把原始字节编码为 Hex、Base64 或 Base64URL。这与浏览器用于 TLS 的是同一套原生、经审计的实现,运行在 JavaScript 引擎之外以求速度。
HMAC 最佳实践
- 密钥长度至少等于哈希输出
- HMAC-SHA256 至少用 32 个随机字节(256 位)的密钥;SHA-512 用 64 个。短密钥或低熵密钥是最薄弱的环节。请从密码学安全的随机源生成密钥 —— 绝不要用口令或可预测的字符串。
- 始终以常量时间比较标签
- 用常量时间比较来校验签名(Node 用 crypto.timingSafeEqual,Python 用 hmac.compare_digest),而不是 == 或字符串相等。朴素比较会在第一个不同字节处提前返回,泄露的时序可能让攻击者逐字节恢复出有效标签。本工具的「校验」标签页已采用常量时间比较。
- 切勿记录或暴露密钥
- 把签名密钥挡在日志、错误信息、URL 和客户端代码之外。将其存放在密钥管理器或环境变量中,定期轮换,并让每个集成各用一把密钥,这样一次泄露不至于殃及全部。
- 优先选 HMAC-SHA256 或更强算法
- 默认用 HMAC-SHA256;当对端要求时升到 SHA-384 或 SHA-512。新系统避免用 HMAC-SHA1,绝不要用 HMAC-MD5。尽管 HMAC 比裸签名更能容忍弱哈希,从现代哈希起步能给你最大的安全余量。
- 对确切字节(含时间戳)签名
- 对原始、未修改的载荷签名 —— 重新序列化 JSON 或修剪空白会改变字节并破坏校验。对请求签名时,把时间戳或 nonce 纳入被签数据,并拒绝过期签名以防重放攻击。
HMAC 常见问题
什么是 HMAC?
HMAC 与 SHA-256 这样的普通哈希有何不同?
如何校验传入的 webhook 签名?
我的服务器用的是哪种密钥和输出编码?
HMAC-SHA256 安全吗?
为什么这里没有 HMAC-MD5 或 HMAC-SHA-3?
JWT 该用 HS256(HMAC)还是 RS256(RSA)?
相关工具
查看所有工具 →Bcrypt 哈希生成器与验证器
安全工具
在线生成并验证 bcrypt 密码哈希——可调成本因子,支持 $2b$/$2a$/$2y$ 前缀。100% 在浏览器中运行,密码绝不上传。
JWT 解码器 · 在线解码工具
安全工具
免费 JWT 解码器,在线即时解码 JWT 令牌。查看头部、载荷、签名以及过期时间、算法和声明详情。100% 浏览器本地运行——令牌绝不离开你的设备。无需注册、无跟踪。
JWT 编码器与生成器
安全工具
免费在线 JWT 生成器与编码器。构建头部和载荷,使用 HS256、RS256 或 ES256 即时签名。100% 浏览器本地运行——你的密钥和私钥绝不离开设备。
免费 JWT 密钥生成器 — HS256/384/512
安全工具
为 HS256/384/512 生成强壮、符合 RFC 规范的 JWT 密钥——100% 在浏览器中运行,绝不发往服务器。支持 base64url、base64 或 hex,可复制到 .env。
在线 MD5 哈希生成器与文件校验工具
安全工具
在线生成 MD5、SHA-256、SHA-1、SHA-512 哈希值 — 完全免费,浏览器本地运算,无需注册。支持文本和文件哈希、校验和验证、哈希值对比,一键复制,数据绝不离开你的设备。
随机密码生成器 — 自定义长度、强度与安全性
安全工具
免费在线随机密码生成器,一键生成高强度安全密码。支持自定义长度、字符类型,批量生成多个密码。所有密码仅在浏览器本地生成,不上传不存储。