C#中的SHA512和Java不同
SHA512 in C # and Java are different
C#和java上有这样的代码,他们里面的sha512是不一样的,有没有办法让sha512的结果完全一样?我理解 BaseConverter 中的问题,在 Java 中模拟 Base64?尝试过
Base64.getEncoder().encodeToString(str);
但是由于 getEncoder() 的原因,我得到了一个错误。我需要图书馆吗?
C# 代码:
public string Hash(string str)
{
string resultStr = String.Empty;
byte[] data = new UTF8Encoding().GetBytes(str);
byte[] result;
SHA512 shaM = new SHA512Managed();
result = shaM.ComputeHash(data);
resultStr = ReverseString(BitConverter.ToString(result).ToLower().Replace("-", String.Empty));
return resultStr.Substring(5, 25);
}
public static string ReverseString(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
Java中的代码:
public String Hash(String str) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.update(str.getBytes("UTF-16LE"));
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String h = Integer.toHexString(0xFF & messageDigest[i]);
while (h.length() < 2)
h = "0" + h;
hexString.append(h);
}
result = hexString.toString().toLowerCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return ReverseString(result).substring(5, 25);
}
public static String ReverseString(String s)
{
return new StringBuilder(s).reverse().toString();
}
您正在散列不同的数据 - 在 Java 中,您正在将字符串转换为 UTF-16:
digest.update(str.getBytes("UTF-16LE"));
在 C# 中,您使用的是 UTF-8:
byte[] data = new UTF8Encoding().GetBytes(str);
(诚然,我不确定您为什么要创建一个新的 UTF8Encoding
而不是使用 Encoding.UTF8
。)
使用不同的输入,您将得到不同的哈希值。
一般来说,诊断此类问题的方法是在转换的每个步骤中比较数据,无论是通过日志记录还是调试。在这种情况下,您有四个转换:
- 消息字符串到消息字节
- 消息字节到哈希字节
- 哈希字节到哈希字符串(十六进制)
- 反向哈希字符串(十六进制)
下次检查每一步的输出,你就会找出问题所在。
(不明显为什么你想要反转十六进制输出,但那是另一回事。)
问题出在散列的输入行中(字符串是没有其余数据的盐,其余数据为空,因为 EditText 的定义有错误(EditText 返回一个空字符串) 并修复了 Java 中 UTF-8 的编码。
C#和java上有这样的代码,他们里面的sha512是不一样的,有没有办法让sha512的结果完全一样?我理解 BaseConverter 中的问题,在 Java 中模拟 Base64?尝试过
Base64.getEncoder().encodeToString(str);
但是由于 getEncoder() 的原因,我得到了一个错误。我需要图书馆吗?
C# 代码:
public string Hash(string str)
{
string resultStr = String.Empty;
byte[] data = new UTF8Encoding().GetBytes(str);
byte[] result;
SHA512 shaM = new SHA512Managed();
result = shaM.ComputeHash(data);
resultStr = ReverseString(BitConverter.ToString(result).ToLower().Replace("-", String.Empty));
return resultStr.Substring(5, 25);
}
public static string ReverseString(string s)
{
char[] charArray = s.ToCharArray();
Array.Reverse(charArray);
return new string(charArray);
}
Java中的代码:
public String Hash(String str) {
try {
MessageDigest digest = MessageDigest.getInstance("SHA-512");
digest.update(str.getBytes("UTF-16LE"));
byte messageDigest[] = digest.digest();
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < messageDigest.length; i++) {
String h = Integer.toHexString(0xFF & messageDigest[i]);
while (h.length() < 2)
h = "0" + h;
hexString.append(h);
}
result = hexString.toString().toLowerCase();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
} catch (UnsupportedEncodingException e) {
e.printStackTrace();
}
return ReverseString(result).substring(5, 25);
}
public static String ReverseString(String s)
{
return new StringBuilder(s).reverse().toString();
}
您正在散列不同的数据 - 在 Java 中,您正在将字符串转换为 UTF-16:
digest.update(str.getBytes("UTF-16LE"));
在 C# 中,您使用的是 UTF-8:
byte[] data = new UTF8Encoding().GetBytes(str);
(诚然,我不确定您为什么要创建一个新的 UTF8Encoding
而不是使用 Encoding.UTF8
。)
使用不同的输入,您将得到不同的哈希值。
一般来说,诊断此类问题的方法是在转换的每个步骤中比较数据,无论是通过日志记录还是调试。在这种情况下,您有四个转换:
- 消息字符串到消息字节
- 消息字节到哈希字节
- 哈希字节到哈希字符串(十六进制)
- 反向哈希字符串(十六进制)
下次检查每一步的输出,你就会找出问题所在。
(不明显为什么你想要反转十六进制输出,但那是另一回事。)
问题出在散列的输入行中(字符串是没有其余数据的盐,其余数据为空,因为 EditText 的定义有错误(EditText 返回一个空字符串) 并修复了 Java 中 UTF-8 的编码。