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.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 

String.getBytes方法使用平台的默认字符集将字符串编码为字节,而您链接的示例代码使用UTF-8。

试试这个:

 digest.update(secret.getBytes("UTF-8")); 

其次, Integer.toHexString方法返回hex结果,没有前导0。

您链接到的C#代码也使用salt – 但Java代码没有。 如果你使用一次盐而不是另一种,那么结果将是(并且应该是!)不同。

 hexString.append(Integer.toHexString(0xFF & hash[i])); 

您正在错误地构建哈希字符串。 Integer.toHexString不包含前导零,因此当Integer.toHexString(0xFF) == "FF" ,问题是Integer.toHexString(0x05) == "5"

建议的更正: String.format("%02x", hash[i] & 0xFF)

你并没有真正写下你如何调用SimpleHash类 – 使用哪些参数等。

但请注意其ComputeHash方法在其文档中有:

散列值格式为base64编码的字符串。

您的类将输出格式化为hex,这显然会有所不同。

此外,salt在SimpleHash中被解释为base64,而您的方法将其解释为ASCII(或者您的系统编码是什么 – 最可能是ASCII兼容的,并且字符串仅包含ASCII字符)。

此外,SimpleHash中的输出包括salt(允许在使用随机盐时将其复制为“validation”部分),这在您的方法中不会。

(其他答案已经提到了更多的观点。)

 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#的#