C#从ASCII文本生成SHA256哈希:等价PHP bin2hex的实现问题
问题分析
你现有代码的核心错误是不符合支付服务要求的哈希流程,跳过了「原始拼接字符串转ASCII十六进制表示」的关键步骤:
- 官方PHP逻辑:原始字符串 → 转ASCII十六进制字符串(
bin2hex)→ 对该十六进制字符串做SHA256运算 → 输出哈希结果 - 原有C#逻辑:原始字符串 → 转ASCII字节 → 直接对原始字节做SHA256运算 → 输出哈希结果
两者输入到SHA256的源数据完全不同,自然得到的哈希值无法匹配。
正确C#实现代码
using System.Text; using System.Security.Cryptography; public string GeneratePaymentHash(string storeName, decimal chargeTotal, string currency, string sharedSecret) { // 第一步:拼接原始待处理字符串 StringBuilder rawSb = new StringBuilder(); rawSb.Append(storeName); rawSb.Append(chargeTotal.ToString("f2")); // 注意确认金额格式与PHP侧完全一致,无千分位、小数固定2位 rawSb.Append(currency); rawSb.Append(sharedSecret); string rawString = rawSb.ToString(); // 第二步:将原始字符串转换为ASCII十六进制表示,等价于PHP的bin2hex StringBuilder hexSb = new StringBuilder(); byte[] rawAsciiBytes = Encoding.ASCII.GetBytes(rawString); foreach (byte b in rawAsciiBytes) { hexSb.Append(b.ToString("x2")); // x2表示输出2位小写十六进制,和bin2hex输出格式一致 } string hexString = hexSb.ToString(); // 第三步:对十六进制字符串做SHA256运算 byte[] hexAsciiBytes = Encoding.ASCII.GetBytes(hexString); using (SHA256 sha256 = SHA256.Create()) { byte[] hashBytes = sha256.ComputeHash(hexAsciiBytes); // 将哈希结果转换为十六进制字符串,和PHP hash函数默认输出格式一致 StringBuilder hashSb = new StringBuilder(); foreach (byte b in hashBytes) { hashSb.Append(b.ToString("x2")); } return hashSb.ToString(); // 如果服务端要求大写哈希,把所有x2改成X2即可 } }
注意事项
- 所有字符编码必须严格使用ASCII,若参数中存在非ASCII字符,需要提前和支付网关确认字符转义规则
- 金额格式需要和PHP侧完全对齐,比如是否需要去掉小数点后末尾的0、是否有千分位分隔符,避免原始拼接字符串不一致
- 十六进制字符串的大小写需要严格匹配,PHP的
bin2hex和hash函数默认输出小写,若网关要求大写可统一修改ToString的格式符为X2
内容的提问来源于stack exchange,提问作者Sparky
相关产品推荐
相关产品推荐

