Node.js crypto-js与Golang crypto/md5处理对象时MD5哈希值差异问题
问题原因解析
crypto-js的MD5方法对输入的处理逻辑如下:
- 当输入不是CryptoJS内部的WordArray类型,也不是字符串类型时,会强制调用输入值的
toString()方法转为字符串再计算哈希 - 普通JS对象调用
toString()的返回值是固定的"[object Object]",和对象内部的键值完全无关 - 你给出的crypto-js输出结果,本质就是字符串
"[object Object]"的MD5值转Base64的结果,和你传入的{"key":"value"}的内容没有关系
为什么Golang代码结果不一致
你Golang代码中先对结构体做了JSON序列化,得到的是{"key":"value"}对应的字节流,再计算MD5,相当于你计算的是JSON字符串的哈希,和crypto-js实际计算的"[object Object]"完全是两个输入,结果自然不同。
修复方案
两种对齐方案,按需选择:
方案1:修改Node.js代码对齐Golang逻辑
给crypto-js传入序列化后的JSON字符串,而不是直接传对象:
var CryptoJS = require("crypto-js"); let body = {"key":"value"} // 先做JSON序列化再计算哈希 let bodyHash = CryptoJS.MD5(JSON.stringify(body)); console.log(CryptoJS.enc.Base64.stringify(bodyHash))
此时输出结果和你当前Golang代码的输出pzU/fN3OgI3gAydHoLe+UA==完全一致。
方案2:修改Golang代码对齐原Node.js逻辑
如果要复现你原来的Node.js代码的输出,直接计算固定字符串的MD5即可:
import ( "crypto/md5" "encoding/base64" ) func main() { bodyStr := "[object Object]" bodyHash := md5.Sum([]byte(bodyStr)) bodyHashBase64 := base64.StdEncoding.EncodeToString(bodyHash[:]) // 输出为SH97IvaDEtLBu8k7GupEWw==,和原Node.js结果一致 }
注意事项
如果选择用JSON序列化后计算哈希的方案,需要保证不同语言的JSON序列化规则完全一致,包括:
- 键的顺序统一
- 没有多余的空格、换行符
- 字符串转义规则统一
否则还是可能出现哈希结果不一致的问题。
内容的提问来源于stack exchange,提问作者Johannes Krämer
相关产品推荐
相关产品推荐

