C#与Java对相同文本加盐SHA256哈希结果不一致问题求助
问题根本原因
- 核心算法实现不匹配:C#侧使用的是
HMACSHA256算法(带密钥的哈希消息认证码算法,基于SHA256实现),Java侧使用的是普通SHA-256消息摘要。你当前Java代码的逻辑是「先将salt写入摘要,再计算文本的哈希」,这是简单的salt拼接哈希逻辑,和HMAC的内部计算规则(包含密钥填充、两轮哈希计算等标准流程)完全不同,是结果不匹配的核心原因。 - salt处理潜在问题:你提供的测试用例
salt=ABCDEFG长度为7,两边代码均以salt长度/2取整作为字节数组长度,仅处理了salt的前6位字符,剩余的第7位字符会被直接丢弃,若实际业务中salt长度为奇数,会存在数据丢失问题。 - 输出格式不统一:C#侧使用
ToString("X2")输出大写十六进制字符串,Java侧当前输出为小写十六进制字符串,即便算法对齐后,直接字符串对比也会判定为不匹配。
修正后的Java实现代码
import javax.crypto.Mac; import javax.crypto.spec.SecretKeySpec; import java.nio.charset.StandardCharsets; public static String sign(String textToHash, String salt) { byte[] convertedHash = new byte[salt.length() / 2]; for (int i = 0; i < salt.length() / 2; i++) { convertedHash[i] = (byte) Integer.parseInt(salt.substring(i * 2, i * 2 + 2), 16); } try { // 替换为HMACSHA256算法实现 Mac mac = Mac.getInstance("HmacSHA256"); SecretKeySpec secretKeySpec = new SecretKeySpec(convertedHash, "HmacSHA256"); mac.init(secretKeySpec); byte[] hashValue = mac.doFinal(textToHash.getBytes(StandardCharsets.UTF_8)); StringBuilder sb = new StringBuilder(); for (byte b : hashValue) { // 转大写和C#输出格式对齐 sb.append(String.format("%02X", b)); } return sb.toString(); } catch (Exception e) { e.printStackTrace(); return null; } }
用上述代码代入你的测试用例计算,即可得到和C#侧完全一致的70B38047C28FFEDCF7275C428E65310671CADB65F11A5C9A8CFBB3CF52112BA3结果。
内容的提问来源于stack exchange,提问作者Karim Alaa
相关产品推荐
相关产品推荐

