C++ Base64编码与Node.js HMAC签名Base64输出结果不一致问题
问题原因
结果不一致和Base64算法实现无关,核心是两个场景的待编码原始数据、输入参数完全不匹配:
- 你的C++ Base64编码函数本身逻辑正确,测试时编码的输入是可读的十六进制ASCII字符串
"4ce808f16d8931a7a69548053c90144f669e765c7a227341179886461b6a9776",和在线编码工具输入一致,结果匹配也验证了这一点。 - Node.js代码里的操作根本不是对上述十六进制字符串做Base64:代码先对
message做HMAC-SHA256运算,再对运算输出的原始二进制字节流做Base64,待编码的原始内容和你C++测试时的输入完全不是一个东西,结果自然不同。 - Node.js里的密钥传入错误:你代码里写的乱码
key是把原始二进制密钥强行按UTF-8解析得到的损坏值,而你手上的十六进制字符串是密钥的十六进制文本表示,不是可以直接传入HMAC的密钥原始字节,错误的密钥会直接导致HMAC计算结果完全错误。
解决方法
- 修正Node.js侧的密钥处理逻辑:先把十六进制格式的密钥字符串转为原始二进制Buffer,再传入HMAC函数,不要使用解析乱码的字符串作为密钥。
修正后的Node.js代码如下:
const crypto = require('crypto'); // 十六进制格式的密钥字符串 const keyHex = "4ce808f16d8931a7a69548053c90144f669e765c7a227341179886461b6a9776"; // 转为HMAC需要的原始二进制字节 const key = Buffer.from(keyHex, 'hex'); const message = "1654503648GET/orders"; const hmac = crypto.createHmac('sha256', key); const cb_access_sign = hmac.update(message).digest('base64'); console.log(cb_access_sign.toString());
- 如果需要C++侧输出和Node.js一致的结果,不要直接对十六进制格式的签名字符串做Base64:先完成HMAC-SHA256运算得到32字节的原始二进制签名结果,再把这32字节二进制数据传入你的Encode函数做Base64即可。如果先把二进制签名转成十六进制文本再编码,得到的结果会和直接编码二进制签名的结果完全不同。
补充:标准HMAC签名的Base64编码都是针对原始二进制签名结果做的,不要对签名的十六进制文本表示做Base64,否则无法和通用SDK、接口校验逻辑对齐。
内容的提问来源于stack exchange,提问作者dopller
相关产品推荐
相关产品推荐

