HMAC 生成结果对不上:用公开样例检查算法、密钥和输出编码
接口联调时,两边都写着 HMAC-SHA256,结果却长得完全不同,先别急着换密钥。十六进制、Base64 和 Base64url 可以表示同一份计算结果;如果直接比较外观,容易把编码差异当成算法错误。
HMAC 生成工具适合用公开数据复现计算,逐项检查输入和输出约定。本文使用标准中的测试向量,密钥和原文都是公开内容,只用于验证工具与程序的计算过程,不用于真实接口鉴权。
先得到一份可以核对的结果
打开 IT 工具中的“HMAC生成”,在明文框完整输入下面一行,结尾不要追加换行:
what do ya want for nothing?
密钥填写 Jefe,注意首字母大写。哈希算法选 HmacSHA256,输出编码选 Hexadecimal (base 16)。页面随输入实时更新,当前结果为:
5bdcc146bf60754e6a042426089575c75a003f089d2739839dec58b964ec3843
这与 RFC 4231 测试案例 2 的 HMAC-SHA256 结果一致。核对时比较完整 64 个十六进制字符,不能只看开头几个字符相同。

这里的密钥输入框接收文本。标准里同时写出的 4a656665 是 Jefe 的十六进制字节表示,不要看到它就把这八个字符直接当成本例的文本密钥。若某个业务提供的是 Base64 或十六进制形式的密钥,需要先弄清协议要求的是解码后的字节,还是这段文本本身。本页没有密钥编码选择项,不能把两种输入方式混为一谈。
算法不变,只切换输出编码
保留明文、密钥和 HmacSHA256,只把输出编码切换为 Base64 (base 64)。本次得到:
W9zBRr9gdU5qBCQmCJV1x1oAPwidJzmDnexYuWTsOEM=
它与前面的十六进制字符串外观不同,表示的仍是同一份 HMAC 字节。这个结果的末尾有一个 =,是本次 Base64 表示中的填充字符。接入方要求哪种表示,就按哪种表示提交,避免将十六进制文本再次做 Base64,误多加一层编码。

继续切换为 Base64url (url safe),本次结果是:
W9zBRr9gdU5qBCQmCJV1x1oAPwidJzmDnexYuWTsOEM
与上一份相比,这个样例最明显的差异是末尾的 = 消失了。Base64url 与普通 Base64 的字符表也有区别,但本次结果没有出现能展示该差别的字符,不能从截图推断所有结果都只差一个等号。是否保留填充、是否允许换行,仍以接入协议为准。

页面还提供 Binary 等输出选项。选择更多编码不会增加 HMAC 本身的安全性,它只改变结果的表达方式。对照时先把双方输出统一到同一种编码,排查会直接得多。
业务计算仍不一致,按输入顺序查
公开样例能对上后,再检查业务数据。先确认哈希算法的完整名称,再确认原文的字节约定和密钥的解释方式,最后检查输出编码。原文中的空格、换行、大小写都属于输入内容;一份 JSON 经过格式化后即使表达相同对象,文本也可能已经改变,不能直接拿它替代签名时的原始文本。
如果协议要求拼接方法名、路径、时间或其他字段,应先按协议构造完整待签名文本,再送入明文框。页面不会替你推断业务的排序和拼接规则,也不会证明服务端确实接受了这次计算。联调时先保存公开样例的配置,再用脱敏的业务样例逐项对照。
HMAC 用于带密钥的消息认证,不提供把结果还原成原文的“解密”操作。计算值一致也只证明在所用约定下结果相同;真实接口中的重放控制、时间窗和权限,仍由业务协议处理。本文中的公开密钥和输出可用于测试记录,请勿用于真实鉴权。