HMAC 签名编码的坑:Go 和 PHP 的不同处理方式
版权声明
我们非常重视原创文章,为尊重知识产权并避免潜在的版权问题,我们在此提供文章的摘要供您初步了解。如果您想要查阅更为详尽的内容,访问作者的公众号页面获取完整文章。
鲁飞
扫码关注公众号
扫码阅读
手机扫码阅读
文章主旨: 跨语言 HMAC 签名在 Base64 编码前,是否先转换为十六进制字符串将导致结果不同,必须统一编码前的数据格式(直接使用二进制)才能保证一致性。
关键要点:
- Go 和 PHP 计算 HMAC 时,默认返回的原始二进制数据或十六进制字符串会影响后续 Base64 编码结果。
- PHP 中
hash_hmac的第四个参数binary决定输出是原始二进制(true)还是十六进制字符串(false,默认)。 - 直接对 HMAC 二进制结果进行 Base64 编码,输出长度固定且数据可还原;先转十六进制再 Base64 会使数据翻倍,结果完全不同。
- 跨语言一致性建议:统一使用二进制数据进行 Base64 编码(PHP 中设置
binary=true,Go 中直接使用base64.StdEncoding.EncodeToString(signatureBytes))。
内容结构:
- 问题引入:HMAC 签名在不同语言中因编码方式不同导致签名结果不同,作者因直接将 PHP 签名算法用 ChatGPT 生成未测试而踩坑。
- 代码示例:展示 Go 和 PHP 两种编码方式(直接 Base64 与先转十六进制再 Base64)的输出差异。
- 原因分析:根本原因是 Base64 编码前的输入数据不同——PHP 的
hash_hmac默认返回十六进制字符串,而 Go 的h.Sum(nil)返回原始二进制;解释了原始二进制与十六进制字符串的区别。 - Base64 编码作用:将二进制转为文本便于传输,不改变数据内容,但输入不同导致输出不同。
- 保证一致性建议:统一使用二进制数据作为 Base64 编码的输入(PHP 中设
binary=true,Go 中直接对二进制编码)。 - 结论:直接对 HMAC 结果进行 Base64 编码可保持数据可还原;先转十六进制再编码会导致数据翻倍且结果不同;跨语言时务必统一编码方式。
文章总结: 本文以实例揭示了 HMAC 签名跨语言编码差异的根本原因,并给出了简单可行的统一解决方案,避免开发中签名验证失败。
鲁飞
鲁飞
扫码关注公众号
还在用多套工具管项目?
一个平台搞定产品、项目、质量与效能,告别整合之苦,实现全流程闭环。
查看方案
鲁飞的其他文章
PHP8正式版发布,带来了注解和JIT
PHP8 正式版已经发布,来看看都有哪些新特性
MacOS 等机器配置 Docker 启用 Remote API
Docker 不仅可以通过本地命令行docker命令进行调用,还可以通过开启远程控制 API,使用 HTTP
解决Docker端口映射无法访问问题
这是一个过于沙雕的问题。
Bitwarden Secrets Manager:简化 DevOps 的机密管理
Bitwarden Secrets Manager 为 DevOps 团队提供了一种更加安全、便捷的方式来管理和集成机密信息。
为 Docsify 自动生成 RSS 订阅
为Docsify等静态站点自动生成RSS订阅
加入社区微信群
与行业大咖零距离交流学习
PMO实践白皮书
白皮书上线
白皮书上线