前端用 HMAC-SHA256 加密为什么结果和后端对不上?

码农丹丹 阅读 87

我正在对接一个 API,要求用 HMAC-SHA256 对请求体签名,但前端算出来的 signature 和后端不一致,排查了一天没找到原因。

我用的是 CryptoJS,key 和 message 都确认过是字符串,也试过 encode UTF-8,但结果还是不对。是不是哪里漏了?

const message = JSON.stringify({ id: 123, action: 'submit' });
const secret = 'mySecretKey';
const hash = CryptoJS.HmacSHA256(message, secret);
const signature = hash.toString(CryptoJS.enc.Hex);
console.log(signature); // 输出和后端不一样
我来解答 赞 10 收藏
二维码
手机扫码查看
2 条解答
设计师玉飞
这个问题听起来挺头疼的。首先,确保前端和后端用的编码方式完全一致。CryptoJS 默认对字符串做了一些处理,有时候会导致不一致。

你可以试试先对 message 做一次 UTF-8 编码,然后再计算 HMAC。修改后的代码可以这样:

const CryptoJS = require('crypto-js');

const message = JSON.stringify({ id: 123, action: 'submit' });
const secret = 'mySecretKey';

// 先对 message 进行 UTF-8 编码
const utf8Message = CryptoJS.enc.Utf8.parse(message);

const hash = CryptoJS.HmacSHA256(utf8Message, secret);
const signature = hash.toString(CryptoJS.enc.Hex);
console.log(signature);


这样处理之后,签名应该会和后端对上了。如果还不一样,那就得检查一下后端是不是对 secret 或者 message 做了其他处理了。希望这能帮到你,别再折腾一天了。
点赞
2026-03-24 08:03
Dev · 恒鑫
问题大概率出在 JSON 序列化顺序上。对象的 key 顺序在不同浏览器/环境下可能不一样,导致签名的字符串不一致。

后端通常是对参数按 key 排序后再拼接签名的,不是直接 JSON.stringify。

自己写个排序后的字符串拼接:

function getSortedString(obj) {
return Object.keys(obj).sort().map(key => {
const value = obj[key];
// 如果是对象递归处理,否则直接转字符串
return key + '=' + (typeof value === 'object' ? JSON.stringify(value) : String(value));
}).join('&');
}

const params = { id: 123, action: 'submit' };
const message = getSortedString(params); // "action=submit&id=123"
const signature = CryptoJS.HmacSHA256(message, secret).toString(CryptoJS.enc.Hex);


你先试试这个,如果还对不上,再看看后端具体怎么拼接的。
点赞
2026-03-16 23:03