С# SHA-256 против Java SHA-256. Разные результаты?

Я хочу преобразовать некоторый код на Java в С#.

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: байт [] хеш = дайджест.дайджест(СОЛЬ); генерирует (первые 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

person Ilyas I    schedule 17.08.2011    source источник
comment
Почему метод называется getMd5Hash, если вы используете "SHA-256"?   -  person dtb    schedule 17.08.2011
comment
Я точно не знаю. Возможно, этот метод генерирует MD5 в прошлом. Мы просто конвертируем проект с java на C#   -  person Ilyas I    schedule 17.08.2011
comment
Как вы решили эту проблему. не могли бы вы обновить исправление здесь, и я также столкнулся с той же проблемой   -  person VinothKumar Subramani    schedule 23.06.2020


Ответы (5)


Метод String.getBytes кодирует строку в байты, используя кодировку платформы по умолчанию, тогда как в приведенном вами примере кода используется UTF-8.

Попробуй это:

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

Во-вторых, метод Integer.toHexString возвращает шестнадцатеричный результат без начальных нулей.

person dtb    schedule 17.08.2011

Код C#, на который вы ссылаетесь, также использует соль, а код Java — нет. Если вы используете соль с одним, но не с другим, то результаты будут (и должны быть!) другими.

person Cocowalla    schedule 17.08.2011
comment
Код включает byte[] hash = digest.digest(SALT);. Разве это не использует соль? - person dtb; 17.08.2011

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

Вы неправильно строите хэш-строку. Integer.toHexString не включает начальные нули, поэтому Integer.toHexString(0xFF) == "FF" проблема в том, что Integer.toHexString(0x05) == "5".

Предлагаемое исправление: String.format("%02x", hash[i] & 0xFF)

person Nayuki    schedule 17.08.2011

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 #

person Tinashe Robert    schedule 03.08.2018

Вы толком не написали как вызвали класс SimpleHash - с какими параметрами и прочее.

Но обратите внимание, что его метод ComputeHash имеет в своей документации:

Хэш-значение в формате строки в кодировке base64.

Вместо этого ваш класс форматирует вывод в шестнадцатеричном формате, который, очевидно, будет другим.

Кроме того, соль в SimpleHash интерпретируется как base64, в то время как ваш метод интерпретирует ее как ASCII (или любую другую кодировку вашей системы - скорее всего, что-то ASCII-совместимое, а строка содержит только символы ASCII).

Кроме того, вывод в SimpleHash включает соль (чтобы позволить воспроизвести ее для части «проверить» при использовании случайной соли), чего нет в вашем методе.

(Другие ответы уже упоминаются в других ответах.)

person Paŭlo Ebermann    schedule 17.08.2011