在Java和C#中计算SHA-1哈希值

8

在Java和C#中计算SHA-1哈希值

我正在尝试在C#应用程序中复制Java应用程序的逻辑。其中之一是生成密码的SHA-1哈希值。不幸的是,我无法从Java和C#获得相同的结果。

C#输出   : 64  0a  b2 ba e0 7b  ed c4 c1 63  f6 79  a7 46  f7 ab 7f  b5 d1 fa
Java输出:164 10a b2 ba e0 17b ed c4 c1 163 f6 179 a7 146 f7 ab 17f b5 d1 fa 

为了尝试找出发生了什么,我一直在使用Eclipse和Visual Studio中的调试器。

1. 检查byte[] key的值:
Java: { 84, 101, 115, 116 } C# : { 84, 101, 115, 116 }
2. 检查byte[] hash的值:
Java: { 100 10 -78 -70 -32 123 ... } C# : { 100 10 78 186 224 123 ... }

我已经阅读了关于此主题的其他帖子,这些帖子大多涉及输入字符串编码,但这些似乎没有帮助我。我的猜测是这与有符号和无符号字节有关,但我在这个方向上没有取得太多进展。任何帮助都将不胜感激。

谢谢,

Karle


Java版本:

public void testHash() {

    String password = "Test";

    byte[] key = password.getBytes();

    MessageDigest md = MessageDigest.getInstance("SHA-1");

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

    String result = "";
    for ( byte b : hash ) {
        result += Integer.toHexString(b + 256) + " ";
    }

    System.out.println(result);

}

C#版本:

public void testHash() {

    String password = "Test";

    byte[] key = System.Text.Encoding.Default.GetBytes(password);

    SHA1 sha1 = SHA1Managed.Create();

    byte[] hash = sha1.ComputeHash(key);

    String result;
    foreach ( byte b in hash ) {
        result += Convert.ToInt32(b).ToString("x2") + " ";
    }

    Console.WriteLine(result);

}

3
你的输出例程不同。在Java代码中,你会将字节值加上256,而在C++中则不会...因为256的十进制等于100的十六进制,这就是你观察到的差异:64 <-> 164 - Daniel Hilgarth
4
Java 中的字节是有符号的,而 C# 中的字节是无符号的。Java 中的 byte 类型相当于 C# 中的 sbyte 类型。 - rossum
2个回答

15
在Java版本中,不要使用b+256,而应该使用b&255。SHA-1部分没有问题,这只是输出内容的问题。Java的"byte"类型是有符号的:它返回介于-128和127之间的值。要获取相应的无符号值,您必须仅在该值为负数时添加256。通过与255进行按位与运算(这就是"& 255"所做的),可以进行正确的转换,二进制级别上是将该值截断为其8个最低有效位。

我想我应该意识到像“163”这样的十六进制值显然高于一个字节的最高值。我按照你建议的更改了代码,现在得到了正确的结果。谢谢,Karle。 - Karle

0

你的问题和答案对我非常有用,但我注意到当密码中有字符“0”时,生成的哈希码是不同的,所以我稍微改了一下代码(用Java语言)。

for (int i = 0; i < hash.length; i++)
    {
        String hex = Integer.toHexString(hash[i]);
        if (hex.length() == 1) hex = "0" + hex;
        hex = hex.substring(hex.length() - 2);
        result += hex;
    }

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接