【问题标题】:Hashing Results From C# and Java are DifferentC# 和 Java 的散列结果不同
【发布时间】:2021-12-25 13:54:22
【问题描述】:

我正在尝试对要从 Java 服务传输到 C# 服务的数据“文本”进行哈希处理。 我使用 SHA256 作为哈希算法,但尽管值和盐相同,但结果却不同。

这是我的 C# sn-p

public 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)int.Parse(salt.Substring(i * 2, 2), NumberStyles.HexNumber);
        
    HMAC hasher = new HMACSHA256(convertedHash);
       
    string hexHash = "";
    using (hasher)
    {
        byte[] hashValue = hasher.ComputeHash(Encoding.UTF8.GetBytes(textToHash));
        foreach (byte b in hashValue)
        {
            hexHash += b.ToString("X2");
        }
    }
    return hexHash;
}

还有,这里是 Java sn-p

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);
    }
    String hashedText = null;
    try {
        MessageDigest md = MessageDigest.getInstance("SHA-256");
        md.update(convertedHash);
        byte[] bytes = md.digest(textToHash.getBytes(StandardCharsets.UTF_8));
        StringBuilder sb = new StringBuilder();
        for (byte aByte : bytes) {
            sb.append(Integer.toString((aByte & 0xff) + 0x100, 16).substring(1));
        }
        hashedText = sb.toString();
    } catch (NoSuchAlgorithmException e) {
        e.printStackTrace();
    }
    return hashedText;
}

在Java中,我也试过

convertedHash = salt.getBytes();

但我也得到了不同的结果。

测试:

salt = ABCDEFG
text = hashme

C# 中的结果

70B38047C28FFEDCF7275C428E65310671CADB65F11A5C9A8CFBB3CF52112BA3

Java 中的结果

a8bc36606aade01591a1d12c8b3c87aca1fe55def79740def03a90b49f2c6b7c

所以,关于为什么结果不一样的任何帮助。

提前致谢。

【问题讨论】:

  • 在 java sn-p 中,`MessageDigest md = MessageDigest.getInstance(algorithm);` 中的“算法”是什么?
  • System.out.printf("Default encoding. Java %s != C# %s%n", Arrays.toString("abc".getBytes()), Arrays.toString("abc".getBytes("UTF-16LE")));
  • 它是“SHA-256”
  • @ElliottFrisch 好的,我得到“默认编码。Java [97, 98, 99] != C# [97, 0, 98, 0, 99, 0]”,但不是 UTF_8 C# 和 Java 一样吗?
  • 在这样的问题中,最好提供示例输入和输出。就像“我尝试用盐 Y 对字符串 X 进行哈希处理,但在 Java 中我得到 A,而在 C# 中我得到 B”

标签: java c# hash cryptography sha


【解决方案1】:

为了模仿 Java 哈希,我在 C# 中使用 SHA256Managed 而不是 HMACSHA256

public static string Sign(string data, string salt)
{
    UTF8Encoding encoder = new UTF8Encoding();
    SHA256Managed sha256hasher = new SHA256Managed();
    byte[] convertedHash = new byte[salt.Length / 2];

    for (int i = 0; i < salt.Length / 2; i++)
        convertedHash[i] = (byte)int.Parse(salt.Substring(i * 2, 2), NumberStyles.HexNumber);

    byte[] dataBytes = encoder.GetBytes(data);
    byte[] bytes = new byte[convertedHash.Length + dataBytes.Length];
    
    Array.Copy(convertedHash, bytes, convertedHash.Length);
    Array.Copy(dataBytes, 0, bytes, convertedHash.Length, dataBytes.Length);
    byte[] hashedBytes = sha256hasher.ComputeHash(bytes);

    return hashedBytes.Aggregate("", (current, t) => current + t.ToString("X2"));
}

HMACSHA256 不是纯粹的SHA-256

【讨论】:

  • 太好了,这确实是一个有用的答案,在我意识到 SHA256 与盐和 SHA256 与 HMAC 之间的区别“这是我想要的,因为它用于验证完整性”之后,我转换了我的 java 代码使用算法“HMACSHA256”而不是“SHA-256”和我在 C# 中使用的相同“哈希到字节”技术,结果变得相同。谢谢你的回答。
猜你喜欢
  • 2014-01-26
  • 2012-12-14
  • 1970-01-01
  • 1970-01-01
  • 2020-02-14
  • 2020-03-12
  • 1970-01-01
  • 2014-09-18
  • 1970-01-01
相关资源
最近更新 更多