我想将一些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!");
}
当我尝试使用the SimpleHash class时,我得到了不同的哈希值
更新
例如:
Java:byte [] hash = digest.digest(SALT); 生成(前6个字节):
[0] = 9
[1] = -95
[2] = -68
[3] = 64
[4] = -11
[5] = 53
....
C#代码(类SimpleHash): string hashValue = Convert.ToBase64String(hashWithSaltBytes); hashWithSaltBytes有(前6个字节):
[0] 175 byte
[1] 209 byte
[2] 120 byte
[3] 74 byte
[4] 74 byte
[5] 227 byte
答案 0 :(得分:7)
String.getBytes method使用平台的默认字符集将字符串编码为字节,而您链接的示例代码使用UTF-8。
试试这个:
digest.update(secret.getBytes("UTF-8"));
其次,Integer.toHexString method返回十六进制结果,没有前导0。
答案 1 :(得分:2)
您链接的C#代码也使用salt - 但Java代码没有。如果你使用salt而不是另一个,那么结果将是(和应该!)不同。
答案 2 :(得分:2)
hexString.append(Integer.toHexString(0xFF & hash[i]));
您正在错误地构建哈希字符串。 Integer.toHexString
不包含前导零,因此在Integer.toHexString(0xFF) == "FF"
时,问题是Integer.toHexString(0x05) == "5"
。
建议更正:String.format("%02x", hash[i] & 0xFF)
答案 3 :(得分:1)
public static String getEncryptedPassword(String clearTextPassword) throws NoSuchAlgorithmException{
MessageDigest md = MessageDigest.getInstance("SHA-256");
md.update(clearTextPassword.getBytes(StandardCharsets.UTF_8));
byte[] digest = md.digest();
String hex = String.format("%064x", new BigInteger(1, digest));
String st = new String(hex.toUpperCase());
for (int i = 2; i < (hex.length() + hex.length() / 2) - 1 ;) {
st = new StringBuffer(st).insert(i, "-").toString();
i = i + 3;
}
return st ;
}
您可以使用以下Java来匹配C#的Java
答案 4 :(得分:0)
你并没有真正写下你如何调用SimpleHash类 - 使用哪些参数等。
但请注意,其ComputeHash
方法在其文档中有:
哈希值,格式为base64编码的字符串。
您的类将输出格式化为十六进制,这显然会有所不同。
此外,salt在SimpleHash中被解释为base64,而您的方法将其解释为ASCII(或者您的系统编码是什么 - 最可能是ASCII兼容的,并且字符串只包含ASCII字符)。
此外,SimpleHash中的输出包括salt(允许在使用随机盐时将其复制为“验证”部分),而在您的方法中则不然。
(其他答案已经提到了更多的观点。)