HMAC 签名

密钥 + 消息算带密钥摘要,附填充与内外层哈希分步演示。

HMAC 是「带密钥的摘要」:普通 SHA-256 只证明内容没被改过,谁都能算;HMAC 还要求来者持有同一把密钥,才能算出同样的签名。它的构造是 RFC 2104 定义的 H(K⊕opad ‖ H(K⊕ipad ‖ 消息)),内层哈希和外层哈希用的是同一个摘要算法,本页把这条链按真实字节逐步列出来,每一步都能自己复算。

算法只列 WebCrypto 支持的 SHA-1/256/384/512,不提供 HMAC-MD5:浏览器里根本没有 MD5,而且 MD5 做 MAC 早已淘汰。签名与验签都在本机完成,密钥和消息不会离开浏览器。

HMAC 签名怎么用

  • 密钥先被补齐成块:密钥要先被处理成固定的分组长度 B:SHA-1/256 的 B 是 64 字节,SHA-384/512 的 B 是 128 字节。密钥比 B 短就右侧补 0,比 B 长就先做一次哈希把它压短——这一步很容易被忽略。
  • 签名:填密钥(可选 UTF-8 文本、Hex 或 Base64 三种格式)和消息,选算法与输出格式,结果区给出签名。签名只算一次:结果区、验签判定和分步演示里的交叉校验共用同一个 WebCrypto 结果,所以改一次密钥不会连着跑三遍——改输出格式或改密钥格式(字节没变)更是零次新计算。
  • 看分步演示:点开「分步演示」(按块展示填充与密钥调度),表格依次显示密钥字节数、是否被哈希压短、补零后的密钥块前 32 字节、K⊕ipad、内层哈希 H(K⊕ipad‖M)、K⊕opad、最终签名,第 7 行是手算链与 WebCrypto 的比对;收起时这段计算从 DOM 和缓存里一起释放。
  • 验签与 API 示例:把模式切到「验签」等于展开「验签」这块折叠(两边是绑定的,收起折叠模式就切回来),粘贴对方给的签名(hex 或 Base64、大小写与空格都不敏感)即可判定;「API 签名示例」默认收起,展开后用当前消息里的 k=v 参数排序加时间戳拼出规范串再签一次——那是一笔不同的输入,所以也单独算。

常见问题

密钥长度超过分组长度会发生什么?

RFC 2104 规定先把密钥哈希一次再补零:SHA-384/512 的 B 是 128 字节,所以 131 字节的密钥会先被 H(key) 压成 48/64 字节(RFC 4231 的用例 6、7 就是专门测这条路径的)。SHA-1/256 的 B 是 64 字节,超过同样会被压短。

空消息能签名吗?

能。HMAC 对空字符串有明确定义,把消息留空就能看到结果——它只依赖密钥和算法,不是报错。RFC 4231 的用例 4 用的就是定长密钥加定长填充数据这一类边界。

为什么大小写不同的签名都算通过?

验签时做的是「去掉空白后统一小写再比字符串」,方便你和文档、日志里的写法对齐。但浏览器里的字符串比较不是常数时间的,所以这个功能只用于本地核对,不能当成线上的安全边界。

对应功能编号 #34无需安装,手机端同样可用按 Ctrl + K 换工具