C#中复现SHA384 HMAC签名遇问题,API签名结果不符预期
解决C#中HMAC-SHA384签名与API文档预期不符的问题
看起来你已经抓到了问题的核心——换行符格式差异导致Base64输出和文档不一致,进而影响最终签名结果。下面我会给出针对性的C#实现方案,帮你完全匹配API的签名规则:
核心问题分析
API要求的签名流程是 signature = hex(HMAC_SHA384(base64(payload), key=api_secret)),但Windows平台默认换行符是\r\n,而API大概率期望Unix风格的\n,所以必须先对payload的换行符做归一化处理,再进行后续步骤。
完整实现代码
以下是严格贴合签名规则的C#代码,每一步都有明确注释:
using System; using System.Security.Cryptography; using System.Text; public class ApiSignatureHelper { public static string GenerateApiSignature(string payload, string apiSecret) { // 1. 归一化换行符:全局替换\r\n为\n,匹配API预期的文本格式 string normalizedPayload = payload.Replace("\r\n", "\n"); // 2. 将处理后的payload转为UTF-8字节数组,再生成Base64字符串 byte[] payloadUtf8 = Encoding.UTF8.GetBytes(normalizedPayload); string base64EncodedPayload = Convert.ToBase64String(payloadUtf8); // 3. 将API密钥转为UTF-8字节数组(确保编码和payload一致) byte[] secretUtf8 = Encoding.UTF8.GetBytes(apiSecret); // 4. 计算HMAC-SHA384哈希值 using (var hmac = new HMACSHA384(secretUtf8)) { byte[] hashBytes = hmac.ComputeHash(Encoding.UTF8.GetBytes(base64EncodedPayload)); // 5. 将哈希字节数组转为十六进制字符串(根据文档示例选择大小写,这里用小写) var hexBuilder = new StringBuilder(); foreach (byte b in hashBytes) { hexBuilder.Append(b.ToString("x2")); } return hexBuilder.ToString(); } } }
关键注意事项
- 换行符兼容:如果payload中存在单独的
\r(比较少见),可以额外添加normalizedPayload = normalizedPayload.Replace("\r", "\n");来覆盖所有情况。 - 编码一致性:所有字符串转字节数组必须使用
Encoding.UTF8,不要依赖系统默认编码(默认编码会随系统环境变化),这是匹配文档结果的核心前提。 - 十六进制大小写:如果文档示例的签名是大写字母,只需将代码中的
"x2"改为"X2"即可。 - 分步验证:先单独输出
base64EncodedPayload和文档示例的Base64结果对比,确认这一步完全一致后,再检查最终签名,这样能快速定位问题所在。
内容的提问来源于stack exchange,提问作者argyle
相关产品推荐
相关产品推荐

