C# SHA-256 与 Java SHA-256。结果不同?
我想将一些 Java 代码转换为 C# 代码。
Java 代码:
private static final byte[] SALT = "NJui8*&N823bVvy03^4N".getBytes();
public static final String getSHA256Hash(String secret)
{
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(secret.getBytes());
byte[] hash = digest.digest(SALT);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
hexString.append(Integer.toHexString(0xFF & hash[i]));
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
throw new RuntimeException("SHA-256 realization algorithm not found in JDK!");
}
当我尝试使用 SimpleHash 类 我得到了不同的哈希值
更新:
例如:
Java: byte[] hash = 摘要.digest(SALT); 生成(前 6 个字节):
[0] = 9
[1] = -95
[2] = -68
[3] = 64
[4] = -11
[5] = 53
....
C# 代码(SimpleHash 类): 字符串 hashValue = Convert.ToBase64String(hashWithSaltBytes); hashWithSaltBytes 有(前 6 个字节):
[0] 175 byte
[1] 209 byte
[2] 120 byte
[3] 74 byte
[4] 74 byte
[5] 227 byte
I want to convert a some code which is in Java to C#.
Java Code:
private static final byte[] SALT = "NJui8*&N823bVvy03^4N".getBytes();
public static final String getSHA256Hash(String secret)
{
try {
MessageDigest digest = MessageDigest.getInstance("SHA-256");
digest.update(secret.getBytes());
byte[] hash = digest.digest(SALT);
StringBuffer hexString = new StringBuffer();
for (int i = 0; i < hash.length; i++) {
hexString.append(Integer.toHexString(0xFF & hash[i]));
}
return hexString.toString();
} catch (NoSuchAlgorithmException e) {
e.printStackTrace();
}
throw new RuntimeException("SHA-256 realization algorithm not found in JDK!");
}
When I tried to use the SimpleHash class I got different hashs
UPDATE:
For example:
Java: byte[] hash = digest.digest(SALT);
generates (first 6 bytes):
[0] = 9
[1] = -95
[2] = -68
[3] = 64
[4] = -11
[5] = 53
....
C# code (class SimpleHash):
string hashValue = Convert.ToBase64String(hashWithSaltBytes);
hashWithSaltBytes has (first 6 bytes):
[0] 175 byte
[1] 209 byte
[2] 120 byte
[3] 74 byte
[4] 74 byte
[5] 227 byte
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(5)
String.getBytes 方法 使用平台的默认字符集将字符串编码为字节,而您链接的示例代码使用 UTF-8。
试试这个:
其次, Integer .toHexString方法返回不带前导0的十六进制结果。
The String.getBytes method encodes the string to bytes using the platform's default charset, whereas the example code you linked uses UTF-8.
Try this:
Secondly, the Integer.toHexString method returns the hexadecimal result with no leading 0s.
您链接到的 C# 代码也使用 salt - 但 Java 代码不使用。如果您只使用一次盐,而不使用其他盐,那么结果将会(并且应该!)不同。
The C# code you link to also uses salt - but the Java code does not. If you use salt with once, but not the other, then the results will be (and should be!) different.
您错误地构建了哈希字符串。
Integer.toHexString
不包含前导零,因此当Integer.toHexString(0xFF) == "FF"
时,问题在于Integer.toHexString(0x05) ==“5”
。建议更正:
String.format("%02x", hash[i] & 0xFF)
You are building the hash string incorrectly.
Integer.toHexString
does not include leading zeros, so whileInteger.toHexString(0xFF) == "FF"
, the problem is thatInteger.toHexString(0x05) == "5"
.Suggested correction:
String.format("%02x", hash[i] & 0xFF)
可以使用下面的java来匹配C#的
You can use the following java to match that of C#
您并没有真正编写如何调用 SimpleHash 类 - 使用哪些参数等等。
但请注意,其
ComputeHash
方法在其文档中有:您的类将输出格式化为十六进制,这显然会有所不同。
另外,Salt 在 SimpleHash 中解释为 base64,而您的方法将其解释为 ASCII(或任何您的系统编码 - 最有可能是 ASCII 兼容的,并且字符串仅包含 ASCII 字符)。
此外,SimpleHash 中的输出包括盐(以允许在使用随机盐时为“验证”部分复制它),而您的方法中没有盐。
(其他答案已经提到了更多要点。)
You didn't really write how you called the SimpleHash class - with which parameters and such.
But note that its
ComputeHash
method has in its documentation:Your class instead formats the output in hexadecimal, which will obviously be different.
Also, the salt is in SimpleHash interpreted as base64, while your method interprets it as ASCII (or whatever your system encoding is - most probably something ASCII-compatible, and the string only contains ASCII characters).
Also, the output in SimpleHash includes the salt (to allow reproducing it for the "verify" part when using random salt), which it doesn't in your method.
(More points are already mentioned by the other answers.)