4

我想将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 类):字符串 hashValue = Convert.ToBase64String(hashWithSaltBytes); hashWithSaltBytes 有(前 6 个字节):

[0] 175 byte
[1] 209 byte
[2] 120 byte
[3] 74  byte
[4] 74  byte
[5] 227 byte
4

5 回答 5

7

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

试试这个:

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

其次,Integer.toHexString 方法返回没有前导 0 的十六进制结果。

于 2011-08-17T15:49:18.733 回答
2

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

于 2011-08-17T15:49:58.030 回答
2
hexString.append(Integer.toHexString(0xFF & hash[i]));

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

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

于 2011-08-17T15:55:38.340 回答
2
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#

于 2018-08-03T14:05:46.813 回答
0

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

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

哈希值格式化为 base64 编码的字符串。

相反,您的课程以十六进制格式化输出,这显然会有所不同。

此外,盐在 SimpleHash 中解释为 base64,而您的方法将其解释为 ASCII(或任何您的系统编码 - 很可能与 ASCII 兼容,并且字符串仅包含 ASCII 字符)。

此外,SimpleHash 中的输出包括盐(以允许在使用随机盐时为“验证”部分复制它),这在您的方法中没有。

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

于 2011-08-17T17:33:20.483 回答