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 签名跨语言编码差异的根本原因,并给出了简单可行的统一解决方案,避免开发中签名验证失败。
鲁飞
鲁飞
扫码关注公众号
还在用多套工具管项目?
一个平台搞定产品、项目、质量与效能,告别整合之苦,实现全流程闭环。
查看方案
鲁飞的其他文章
Swoole v4.6 版本新特性之 SNI 支持
Swoole 在 v4.6.0 版本中对 SNI 进行了支持,这篇文章就对这个新特性进行一些演示和说明。
MacOS 等机器配置 Docker 启用 Remote API
Docker 不仅可以通过本地命令行docker命令进行调用,还可以通过开启远程控制 API,使用 HTTP
使用 acme.sh 自动申请并更新泛域名证书
通过 acme.sh,不仅可以快速申请泛域名证书,还能轻松实现自动更新,降低了 SSL 证书管理的复杂度。
Think-Swoole如何设置Swoole提供的配置项
think-swoole 的文档极少,官方文档中也只是说了如何启动、热更新、连接池等配置
PIE:PHP 扩展管理的未来,替代 PECL 的新选择
PIE 是一个为 PHP 提供扩展安装和管理的新工具,旨在替代传统的 PECL
加入社区微信群
与行业大咖零距离交流学习
PMO实践白皮书
白皮书上线
白皮书上线