MessageDigest хеширует по-другому на различных машинах

У меня есть проблема с MessageDigest, возвращая различные значения хэш-функции на различных компьютерах.

Один компьютер выполняет 32-разрядный Java на Windows Vista, и другой выполняет 64-разрядный Java на Mac OS. Я не уверен, является ли это, потому что MessageDigest является зависимым машины, или я должен явно указать кодировку символов где-нибудь или возможно что-то еще. Вот код:

public static boolean authenticate(String salt, String encryptedPassword, 
    char[] plainTextPassword ) throws NoSuchAlgorithmException {

    // do I need to explcitly specify character encoding here? -->
    String saltPlusPlainTextPassword = salt + new String(plainTextPassword);

    MessageDigest sha = MessageDigest.getInstance("SHA-512");

    // is this machine dependent? -->
    sha.update(saltPlusPlainTextPassword.getBytes());
    byte[] hashedByteArray = sha.digest();

    // or... perhaps theres a translation problem here? -->
    String hashed = new String(hashedByteArray);

    return hashed.equals(encryptedPassword);
}

Этот код должен выполниться по-другому на этих двух различных машинах? Если это зависит машина путем, я записал это, есть ли другой дорожный хеш эти пароли, который является более портативным?Спасибо!

Править:::::

Это - код, который я использую для генерации солей:

public static String getSalt() {
   int size = 16;
   byte[] bytes = new byte[size];
   new Random().nextBytes(bytes);
   return org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(bytes);
}

Решение:::

Благодаря принятому решению я смог исправить свой код:

public static boolean authenticate_(String salt, String encryptedPassword, 
        char[] plainTextPassword ) throws NoSuchAlgorithmException, UnsupportedEncodingException {

        // This was ok
        String saltPlusPlainTextPassword = salt + new String(plainTextPassword);    

        MessageDigest sha = MessageDigest.getInstance("SHA-512");

        // must specify "UTF-8" encoding
        sha.update(saltPlusPlainTextPassword.getBytes("UTF-8"));
        byte[] hashedByteArray = sha.digest();

        // Use Base64 encoding here -->
        String hashed = org.apache.commons.codec.binary.Base64.encodeBase64URLSafeString(hashedByteArray);

        return hashed.equals(encryptedPassword);
    }
10
задан Chris Dutrow 22 June 2010 в 21:04
поделиться

2 ответа

Кодировки вызывают проблемы. Сначала здесь:

saltPlusPlainTextPassword.getBytes()

Это будет использовать кодировку по умолчанию для машины . Плохая идея. Укажите "UTF-8" как простое решение. (Он гарантированно присутствует.)

Далее это вызывает проблемы:

String hashed = new String(hashedByteArray);

hashedByteArray - произвольные двоичные данные. Чтобы безопасно преобразовать его в текст, используйте кодировку base-64 или просто шестнадцатеричную. Опять же, в настоящее время вы используете кодировку по умолчанию, которая будет отличаться от машины к машине. Существует множество сторонних библиотек для кодирования base64 в Java.

17
ответ дан 3 December 2019 в 18:31
поделиться

Вероятно, причиной является решение Джона Скита, приведенное выше, и его рекомендации следует обязательно принять во внимание, но другой возможной причиной является неправильное понимание соли.

Соль - это полусекретное случайное значение, которое применяется к строке перед хэшированием. Это усложняет проведение атаки "грубой силы" при попытке угадать происхождение строки, поскольку соль предположительно неизвестна атакующему.

Значения соли обычно различаются в зависимости от установки. Возможно, причина в том, что на разных машинах значения соли установлены по-разному.

4
ответ дан 3 December 2019 в 18:31
поделиться
Другие вопросы по тегам:

Похожие вопросы: