You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

C#与Python实现HMACSHA256签名结果不一致问题求助

问题:C#与Python HMAC-SHA256签名结果不一致

我在对接客户API时遇到了HMAC签名不匹配的问题:客户提供C#授权示例,我方用Python开发。已确认密钥字节数组和消息字节两端完全一致(Python的base64.b64decode(secretKey)与C#的Convert.FromBase64String(secretKey)结果相同),但签名计算结果却不一样。

C# 签名代码片段:

using (HMACSHA256 sha = new HMACSHA256(secretKeyByteArray))
{
    // Sign the request
    byte[] signatureBytes = sha.ComputeHash(signature);
}

Python 签名代码片段:

signature_hmac = hmac.new(
    base64.b64decode(secretKey),
    bytes(message, "utf8"),
    digestmod=hashlib.sha256,
)

可能的原因及排查方向

  1. 消息编码不匹配
    Python中用bytes(message, "utf8")转换消息,但如果C#端的signature变量是通过Encoding.Unicode.GetBytes(message)(UTF-16编码)生成的字节数组,两端的消息字节会完全不同,直接导致签名差异。优先确认C#端消息的编码方式。

  2. 消息内容的隐性差异
    检查C#的signature参数是否经过额外处理:比如是否是URL编码后的字符串、是否包含隐藏的换行/空格、或是已经经过Base64编码的字节数组,而非原始消息的字节。这些细节都会让两端的输入消息本质不同。

  3. 签名结果的取值/处理差异
    Python的signature_hmac.digest()返回原始字节数组,和C#sha.ComputeHash()的返回值是直接对应的。但如果C#后续对签名做了Base64编码(比如Convert.ToBase64String(signatureBytes)),而你用Python的原始字节去对比,自然会不匹配;反之如果Python用了hexdigest(),也会和C#的原始字节不一致。

  4. 极端情况:密钥的隐性处理
    虽然你确认了Base64解码后的字节一致,但可以再验证一次:分别打印两端密钥字节的十六进制字符串(C#用BitConverter.ToString(secretKeyByteArray).Replace("-", ""),Python用base64.b64decode(secretKey).hex()),确保完全一致。


快速验证方法

找一段固定的测试消息和密钥,分别打印两端的消息字节和签名字节的十六进制字符串直接对比:

  • C#获取消息十六进制:BitConverter.ToString(signature).Replace("-", "")
  • Python获取消息十六进制:message.encode('utf-8').hex()
  • 签名十六进制对比同理,C#用BitConverter.ToString(signatureBytes).Replace("-", ""),Python用signature_hmac.digest().hex()

这样能快速定位是消息输入的问题,还是签名计算的问题。

内容的提问来源于stack exchange,提问作者Rohit

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.25 07:36:18