Skip to content

HMAC 生成器与签名校验工具

免费在线 HMAC 生成与校验工具。支持文本、Hex 或 Base64 密钥计算 HMAC-SHA256/SHA1/SHA384/SHA512,输出 Hex/Base64/Base64URL。100% 在浏览器中运行 —— 密钥永不离开页面。

无追踪 浏览器中运行 免费
100% 在你的浏览器中 —— 你的消息和密钥绝不离开你的设备。
生成的 HMAC

什么是 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. 1

    选择算法

    选 HMAC-SHA256(默认值,也几乎适用于所有 webhook、API 和 JWT),或切到 SHA-1、SHA-384、SHA-512 以匹配某个要求它的系统。这四种都通过 Web Crypto API 在你的浏览器中原生运行。

  2. 2

    输入密钥并设置其编码

    键入或粘贴你的密钥,然后把「密钥编码」设为与服务器解释方式一致:普通字符串用 Text(UTF-8),十六进制数据用 Hex,base64 密钥用 Base64。设错这一项是 HMAC 不匹配的头号原因,拿不准时三种都试一遍。

  3. 3

    输入消息

    粘贴你想签名的确切字节 —— 对 webhook 而言就是逐字节的原始请求体,不做任何重新序列化或空白改动。HMAC 会随你的编辑实时重算,不会向任何服务器发送数据。

  4. 4

    选择输出格式并复制

    选择 Hex(GitHub 风格)、Base64(Stripe/AWS 风格)或 Base64URL(JWT 风格)以匹配你的集成所需,然后点击「复制」获取签名。

  5. 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(基于哈希的消息认证码)是一种用共享密钥同时证明消息完整性与真实性的方法。你把消息和密钥按 RFC 2104 定义的特定嵌套结构喂给哈希函数(这里是 SHA-1、SHA-256、SHA-384 或 SHA-512),得到一个定长标签。任何知道密钥的人都能重新计算这个标签,确认消息未被篡改且来自持有密钥的一方。它是 webhook 签名、签名 API 请求以及 HS256 系列 JWT 令牌背后的标准机制。
HMAC 与 SHA-256 这样的普通哈希有何不同?
像 SHA-256 这样的普通哈希只能证明完整性:任何人都能重算它,所以任何人也能为被篡改的消息伪造出匹配的哈希。HMAC 混入了一个密钥,因此只有持有该密钥的各方才能产生或校验有效标签 —— 这在完整性之上增加了真实性。HMAC 还采用嵌套的两遍结构(用密钥派生的 pad 做内层与外层哈希),使其免疫会影响裸 SHA-1 和 SHA-256 的长度扩展攻击。简而言之:用哈希检测意外损坏,用 HMAC 检测不知道你密钥的攻击者的蓄意篡改。
如何校验传入的 webhook 签名?
取收到的原始请求体(不要重新序列化 JSON —— 即便只是重排键也会让签名失效),选择与服务商相同的算法(通常是 HMAC-SHA256),用正确的「密钥编码」输入你的签名密钥,并把「输出格式」设为与请求头匹配(GitHub 的 sha256= 前缀用 Hex,Stripe/Twilio 风格的请求头用 Base64)。然后打开「校验」标签页,粘贴请求头中的签名(例如 X-Hub-Signature-256),工具会用常量时间比较报告匹配或不匹配。只有在匹配时才信任该载荷。
我的服务器用的是哪种密钥和输出编码?
没有通用答案 —— 它取决于你的服务商,这正是本工具把两者都做成显式选项的原因。常见模式:GitHub 用 UTF-8 文本密钥、小写 hex 输出并带 sha256= 前缀;Stripe 用文本密钥和 base64;AWS Signature V4 用派生的二进制密钥和 hex;许多内部系统发放 base64 或 hex 密钥,必须先解码为原始字节再签名。如果你的 HMAC 对不上,几乎总是编码在作怪 —— 用 Text、Hex、Base64 分别试同一个密钥,找出服务器期望的解释方式。
HMAC-SHA256 安全吗?
安全。HMAC-SHA256 被广泛认为是安全的,也是消息认证的推荐默认值。它的安全性来自 HMAC 结构加上强底层哈希;即便裸哈希存在碰撞攻击,它依然安全 —— HMAC 不像数字签名那样依赖抗碰撞性。现实中的风险是运维层面的而非算法层面的:密钥弱或泄露、把密钥写进日志、或使用非常量时间比较。用一把又长又随机的密钥、并以常量时间比较标签,HMAC-SHA256 就能稳如磐石。
为什么这里没有 HMAC-MD5 或 HMAC-SHA-3?
这是有意为之。本工具只提供 SHA-1、SHA-256、SHA-384 和 SHA-512,因为它们是浏览器原生 Web Crypto API 支持的哈希函数,这让一切都快速且完全在客户端运行、无需额外库。略去 HMAC-MD5 是因为 MD5 已过时,新系统不应再用它。略去 HMAC-SHA-3 是因为 Web Crypto 未实现 SHA-3;加上它就得引入 JavaScript polyfill。况且对几乎所有现代用例,HMAC-SHA256 本就是正确选择。
JWT 该用 HS256(HMAC)还是 RS256(RSA)?
HS256 用单个共享密钥通过 HMAC-SHA256 对 JWT 签名和校验,而 RS256 用 RSA 私钥签名、用配对的公钥校验。当同一方既签发又校验令牌时(单体应用,或能安全共享密钥的可信内部服务)用 HS256 —— 它更简单也更快。当第三方或众多服务必须校验令牌但不能签发令牌时用 RS256,因为你可以只分发公钥。你可以在 JWT 编码器中探查二者的编码结构;HS256 签名正是对头部和载荷做的一次 HMAC-SHA256。

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 哈希值 — 完全免费,浏览器本地运算,无需注册。支持文本和文件哈希、校验和验证、哈希值对比,一键复制,数据绝不离开你的设备。

随机密码生成器 — 自定义长度、强度与安全性

安全工具

免费在线随机密码生成器,一键生成高强度安全密码。支持自定义长度、字符类型,批量生成多个密码。所有密码仅在浏览器本地生成,不上传不存储。