我正在尝试在C#应用程序中复制Java应用程序的逻辑。部分原因是生成密码的SHA-1哈希。不幸的是,我无法从Java和C#中获得相同的结果。
C# Output : 64 0a b2 ba e0 7b ed c4 c1 63 f6 79 a7 46 f7 ab 7f b5 d1 fa Java Output: 164 10a b2 ba e0 17b ed c4 c1 163 f6 179 a7 146 f7 ab 17f b5 d1 fa
为了尝试弄清楚发生了什么,我一直在使用Eclipse和Visual Studio中的调试器。
1. Check values of byte[] key: Java: { 84, 101, 115, 116 } C# : { 84, 101, 115, 116 } 2. Check value of byte[] hash: Java: { 100 10 -78 -70 -32 123 ... } C# : { 100 10 78 186 224 123 ... }
我已经阅读了关于这个主题的其他帖子,主要是指输入字符串编码,但这些似乎没有帮助我。我的猜测是这与有符号和无符号字节有关,但我在这条轨道上没有取得多大进展。任何帮助将不胜感激。
谢谢,
Karle
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);
}
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);
}
答案 0 :(得分:13)
在Java版本中,请勿使用b + 256
;相反,使用b & 255
。 SHA-1部分很好,这只是打印输出的问题。 Java的“byte
”类型已签名:它返回-128到127之间的值。要获得相应的无符号值,只有在值为负时才必须添加256 。
与255的按位AND(即“& 255
”所做的)操作正确的转换,在二进制级别,将值截断为其8个最低有效位。
答案 1 :(得分: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;
}