HMAC 在线计算与签名校验

在线计算 HMAC-SHA256、SHA-512、SHA-1、MD5,密钥可用文本、十六进制或 Base64;内置钉钉加签、飞书签名、GitHub、Stripe 等格式,粘贴签名即可核对,验签失败时给出可能原因。

  • 在浏览器中处理
  • 数据不离开你的设备
  • 免费 · 无需注册
「自定义 HMAC」可填任意密钥和消息,算法自选。其余格式按对应平台文档的规则拼出签名串,算法固定,并多出一行「要发送的值」,写成该平台使用的请求头或参数。飞书、钉钉和 NAVER Cloud 是对你发出的请求签名,所以没有请求体输入框。「示例」填入平台文档公布的测试数据,只在有这类数据的格式下显示。
位 只保留 HMAC 最左边的若干位(RFC 2104 §5),三种写法都按截断后的字节输出。填 8 的倍数,最小 8,最大为完整长度;留空则输出完整结果。少于输出的一半或少于 80 位时会有提示。只在「自定义 HMAC」下可用。

参与签名的字节。「自定义 HMAC」下可以是文本(按 UTF-8 编码)、十六进制或 Base64;其余格式把原始请求体当作文本。文本框里的换行一律是 LF,发送方用 CRLF 时请选 CRLF。十六进制可带空格、冒号和开头的 0x。Base64 可用标准或 URL 安全字母表,有无填充都能读。十六进制和 Base64 里用输入法打出的全角字符按半角读取。GBK、Shift_JIS、EUC-KR 编码的文本要以十六进制粘贴。
「自定义 HMAC」下密钥可以是文本(UTF-8)、十六进制或 Base64。其余格式按平台的规定读取:多数当作文本(Stripe 连同 whsec_ 前缀一起),Chatwork 先做 Base64 解码,Standard Webhooks 取 whsec_ 后面的部分做 Base64 解码。密钥超过哈希分组长度(64 字节,SHA-384 和 SHA-512 为 128 字节)时,HMAC 先对它做一次哈希;不足时补零(RFC 2104)。密钥超过分组长度或短于输出长度时会有提示。文本密钥两端的空格也算密钥的一部分。
结果 随输入实时更新。Hex、Base64、Base64url 三行是同一组字节的三种写法。平台格式下多出的「要发送的值」是该平台实际使用的请求头或参数。「签名串」显示进入 HMAC 的原文,换行和制表符以可见符号标出。焦点在工具内时按 Ctrl+L(Mac 为 ⌘+L)清空各文本框。

填入密钥或消息后,HMAC 显示在这里。

粘贴收到的签名:sha256=…、t=…,v1=…、v1,… 这类请求头,带 sign=… 的钉钉 URL,或单独的十六进制、Base64 值。比较的是字节,所以十六进制(大小写均可)和 Base64 都能读;截断后的值不少于 10 字节时按前缀匹配。不一致时,工具逐个尝试常见原因(末尾换行、CRLF、两端空格、JSON 被重新格式化、密钥编码、密钥与消息对调、其他算法),指出第一个能算出所粘贴值的原因。服务端比较签名请用常数时间比较。

密钥、消息和签名都在本标签页内用 Web Crypto API 计算,不上传、不保存,刷新页面即清空。

阅读完整使用指南 HMAC 生成器:SHA-256 消息认证码原理与实战指南
示例、说明与常见问题 带实际输出的示例、与同类工具的差别,以及常见问题。

计算按 RFC 2104 进行:密钥超过分组长度(SHA-256 为 64 字节,SHA-512 为 128 字节)时先做一次哈希,短于输出长度时工具会提示(RFC 2104 §3 不建议这样用)。

钉钉加签与飞书签名

钉钉文档《自定义机器人安全设置》(2024-02-23 更新)的做法是:把 timestamp + "\n" + secret 当签名字符串,用 HmacSHA256 计算,再 Base64、再 URL 编码。时间戳单位是毫秒,与调用时间相差不能超过 1 小时。用文档示例代码里的密钥 this is secret 和时间戳 1700000000000,选「钉钉自定义机器人加签」得到:

&timestamp=1700000000000&sign=sSFWELbV2YwjdDQhWZwTcWlX5BWUx5J6TPpsZmuPii0%3D

把这段拼在 https://oapi.dingtalk.com/robot/send?access_token=… 后面即可。注意末尾的 = 已编码成 %3D,+ 和 / 也会编码,与 Python urllib.parse.quote_plus 的结果一致。

飞书文档《自定义机器人使用指南》的规则正好相反:timestamp + "\n" + 密钥 是 HMAC 的密钥,被签名的消息为空,时间戳单位是秒。用文档 Java 示例的 demo 和 1599360473:

l1N0gAcBjdwBvGm1xMjOF0XSyaLRpR7tuO5dHfhAYc8=

timestamp 和 sign 都放进请求体 JSON。如果把飞书的签名按钉钉的方法算,同样的输入会得到 DkEDUyVo…,飞书会返回 19021「sign match fail」。在「要核对的签名」里粘贴一个按另一种方法算出的值,工具会提示「与钉钉自定义机器人加签的算法一致」。

飞书的密钥里有换行。多数在线 HMAC 工具的密钥框是单行输入框,换行会被吞掉,只能先把密钥换成十六进制;本工具的飞书格式直接按文档拼接,签名串一栏会把换行显示成 ␊。

企业微信「消息推送配置说明」(2025-08-07 更新)只用 Webhook 地址里的 key 参数,没有签名参数,所以这里没有对应格式。

中文按 GBK 编码时

工具把文本按 UTF-8 转成字节。「签名」两个字在 UTF-8 里是 6 个字节,在 GBK 里是 c7a9c3fb 4 个字节,HMAC 自然不同。用密钥 key:

UTF-8:3139363a3f515a075646cedcdc38fb5362e3dcfa20149ddb43f9cfa1e2c99d9b

GBK(消息编码选十六进制,填 c7a9c3fb):6529b61f2eeb2d0d6499bc4e3bb0ab98fd519c7e4208df9781d0cc51eaa7a83f

老系统的签名规则如果写着「按 GBK 拼接」,先把原文转成 GBK 十六进制再填进来。

与其他在线工具的差别

2026-10-01 用 GitHub 文档的示例实测。在线工具大全 lddgo 结果正确,但每次计算都把消息和密钥以 JSON POST 到 openapi.lddgo.net,消息为空时提示「必填字段不能为空」,算不了飞书这种空消息的签名。CodeShack 在浏览器里计算,但密钥只能填文本,输入框是单行的,也没有验签功能。本工具全部在本页计算,十六进制和 Base64 输入出错时指出第几个字符,验签不一致时给出可能原因。

限制

  • 算法:MD5、SHA-1、SHA-224、SHA-256、SHA-384、SHA-512。不含 SHA-3 和国密 SM3(Web Crypto API 都不提供)。
  • 文本框会把所有换行变成 LF;发送方用 CRLF 时请选 CRLF,其他特殊字节请改用十六进制或 Base64 输入。
  • 浏览器里的比较只用于调试。服务端要用原始请求体字节和常数时间比较。JWT 的 HS256 也是 HMAC-SHA256,可用 JWT 生成器 处理。

不带密钥的摘要请用哈希生成器,基于 HMAC-SHA1 的动态验证码请用 2FA 验证码生成器。

FAQ

密钥会上传或保存吗?

不会。SHA-1、SHA-256、SHA-384、SHA-512 用浏览器自带的 Web Crypto API 计算,MD5 和 SHA-224 用页面内的代码计算。工具不发网络请求,不把密钥和消息写进 localStorage、Cookie 或网址;本页也不加载统计和广告脚本。刷新页面后所有输入都会清空。

钉钉加签和飞书签名有什么区别?

两者都用 HmacSHA256 和 Base64,但用法相反。钉钉把加签密钥当 HMAC 密钥,把「毫秒时间戳 + 换行 + 密钥」当消息,结果还要 URL 编码后拼到 sign 参数。飞书把「秒级时间戳 + 换行 + 密钥」整个当 HMAC 密钥,消息为空。时间戳都要在 1 小时以内。选错格式时,本工具会在核对结果里指出。

企业微信群机器人怎么加签?

企业微信「消息推送」(群机器人)的文档(2025-08-07 更新)只给出带 key 参数的 Webhook 地址,没有签名或时间戳参数,安全性全靠地址保密。需要验签的场景请用钉钉或飞书机器人,或在自己的服务端加一层校验。

验签总是不一致,常见原因有哪些?

最常见的是参与计算的字节和发送方不同:请求体被框架解析后重新序列化、末尾多了或少了换行、换行符在 LF 和 CRLF 之间变了、时间戳单位用错(钉钉是毫秒,飞书是秒)、中文按 GBK 而不是 UTF-8 编码。把收到的签名粘贴到「要核对的签名」,工具会逐一尝试这些情况并告诉你是哪一种。

服务端比较签名能直接用 == 吗?

不建议。请用常数时间比较:Java 的 MessageDigest.isEqual、Python 的 hmac.compare_digest、Go 的 hmac.Equal、Node.js 的 crypto.timingSafeEqual(长度不同时会抛错,先比长度)。本工具的比较只在你的浏览器里进行,不涉及计时问题。