java - Java 和 C# 上的 SHA-1 哈希

标签 java c# hash

我正在尝试使用 SHA-1 验证 XML 节点的内容,基本上,我们使用该节点的内容生成 SHA-1 哈希,并且双方(客户端 C# 和服务器 Java)应该具有完全相同的内容哈希。

问题是,我用 diff 工具检查了两个文本的内容,没有任何区别。但我得到的哈希值与客户端不同。

C# 哈希:60-53-58-69-29-EB-53-BD-85-31-79-28-A0-F9-42-B6-DE-1B-A6-0A

Java 哈希:E79D7E6F2A6F5D776447714D896D4C3A0CBC793

客户端(C#)生成哈希的方式是这样的:

try
    {
        Byte[] stream = null;
        using (System.Security.Cryptography.SHA1CryptoServiceProvider shaProvider = new System.Security.Cryptography.SHA1CryptoServiceProvider())
        {
            stream = shaProvider.ComputeHash(System.Text.Encoding.UTF8.GetBytes(text));
            if (stream == null)
            {
                hash = "Error";
            }
            else
            {
                hash = System.BitConverter.ToString(stream);
            }
        }
    }
    catch (Exception error)
    {
        hash = string.Format("Error SHA-1: {0}", error);
    }
    return hash;

这就是服务器(Java)生成哈希的方式:

        byte[] key = content.getBytes();


        MessageDigest md = MessageDigest.getInstance("SHA1");

        byte[] hash = md.digest(key);

        String result = "";
        for (byte b : hash) {
            result += Integer.toHexString(b & 255);
        }
        return result.toUpperCase();

有人可以帮助我吗? ..谢谢:)

更新: 为了检查发生了什么,我检查了在 C# 中获取 SHA1 哈希的其他方法,我发现了这个:

/// <summary>
        /// Compute hash for string encoded as UTF8
        /// </summary>
        /// <param name="s">String to be hashed</param>
        /// <returns>40-character hex string</returns>
        public static string SHA1HashStringForUTF8String(string s)
        {
            byte[] bytes = Encoding.UTF8.GetBytes(s);

            using (var sha1 = SHA1.Create())
            {
                byte[] hashBytes = sha1.ComputeHash(bytes);
                return System.BitConverter.ToString(hashBytes).Replace("-",string.Empty);
            }
        }

此代码给出以下输出:

E79D07E6F2A6F5D776447714D896D4C3A0CBC793

还有!!我刚刚注意到 Python 给出了相同的输出(抱歉,我应该仔细检查一下)

所以这就是交易

使用此提供程序:System.Security.Cryptography.SHA1CryptoServiceProvider shaProvider = new System.Security.Cryptography.SHA1CryptoServiceProvider()

在三台不同的机器上给出完全不同的输出..

C# 中使用上述方法会得到与 python 相同的结果,而且,由于某种原因Java 会给出截然不同的输出:

E79D7E6F2A6F5D776447714D896D4C3A0CBC793

想法?,是java的问题吗? java上的字节到十六进制方法有问题吗?还有另一种选择吗?

最佳答案

尝试使用它作为 C# 中的哈希:

static string Hash(string input)
    {
        using (SHA1Managed sha1 = new SHA1Managed())
        {
            var hash = sha1.ComputeHash(Encoding.UTF8.GetBytes(input));
            var sb = new StringBuilder(hash.Length * 2);

            foreach (byte b in hash)
            {
                // can be "x2" if you want lowercase
                sb.Append(b.ToString("x2"));
            }

            return sb.ToString();
        }
    }
Hash("test"); //a94a8fe5ccb19ba61c4c0873d391e987982fbbd3

然后使用它作为您的 Java 散列:

private static String convertToHex(byte[] data) {
    StringBuilder buf = new StringBuilder();
    for (byte b : data) {
        int halfbyte = (b >>> 4) & 0x0F;
        int two_halfs = 0;
        do {
            buf.append((0 <= halfbyte) && (halfbyte <= 9) ? (char) ('0' + halfbyte) : (char) ('a' + (halfbyte - 10)));
            halfbyte = b & 0x0F;
        } while (two_halfs++ < 1);
    }
    return buf.toString();
}

public static String SHA1(String text) throws NoSuchAlgorithmException, UnsupportedEncodingException {
    MessageDigest md = MessageDigest.getInstance("SHA-1");
    byte[] textBytes = text.getBytes("iso-8859-1");
    md.update(textBytes, 0, textBytes.length);
    byte[] sha1hash = md.digest();
    return convertToHex(sha1hash);
}
SHA1("test"); //a94a8fe5ccb19ba61c4c0873d391e987982fbbd3

请注意,您需要以下导入:

import java.io.UnsupportedEncodingException; import
java.security.MessageDigest; import
java.security.NoSuchAlgorithmException;

Throws declarations are option, adjust to best fit your code!

关于java - Java 和 C# 上的 SHA-1 哈希,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/40091771/

相关文章:

java - Spark Streaming Word Count 错误/语法

java - JSP异常处理

c# - 为 ListView 设置 ItemSource 在 iOS 上会崩溃,但在 Android 上工作正常

c++ - 将 ruby​​ 哈希转换为 c++ 映射

ruby - 在特定键的哈希数组中查找重复项

java - 如何修改 JavaFX 8 的 DatePicker 上的月份和年份控件?

java - 如何在android中将单个字符串转换为JsonArray?

支持字符串资源的 c# 自定义属性不加载本地化资源

c# - Entity Framework 代码优先 : Generate SQL script with 'Update-Database' produces XML error while parsing

ruby - 继承 Ruby Hash,对象没有 Hash 的方法?