2012-01-04 3 views
2

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

public synchronized String encrypt(String token) { 
    try { 
     MessageDigest sha = MessageDigest.getInstance("SHA"); 
     sha.reset(); 
     sha.update(token.getBytes("UTF-8")); 
     byte[] raw = sha.digest(); 
     System.out.println("raw = " + raw.toString()); 
     String hash = Base64.encodeBase64(raw).toString(); 
     return hash; 
    } catch (Exception e) { 
    } 

    return token; 
} 
+0

Добавить тег соответствующих языков. Я считаю, что вы забыли добавить 'Java'. –

+0

Спасибо, добавлено. – tom

+0

SHA - ** NOT ** шифрование. – Dan

ответ

5

Вы действительно не дали достаточно информации, но я подозреваю, что вы отвлекаясь на это:

System.out.println("raw = " + raw.toString()); 

Это собирается напечатать что-то вроде [[email protected], который не имеет ничего делать с данные в массиве байтов. Вы должны распечатать hash вместо этого - то, что должно быть одинаковым для всех вызовов, если ваш token действительно то же самое.

(Как отмечает Дэн, ваш метод ненадо имени: хеширование не шифрование Также, пожалуйста, не поймать Exceptionили просто проглотит исключения, как это кажется довольно странным, чтобы просто вернуться token на провал,.. тоже.)

EDIT: Как уже отмечалось, я предположил, что Base64.encode фактически возвращает строку, которой она может не быть. Я бы порекомендовал this base64 implementation, который является общедоступным и имеет разумный API - вызовы кодирования возвращают String, что вполне уместно. Конечно, вам тогда не нужен явный вызов toString() ...

+0

Спасибо за уловы! Каковы дополнительные шаги, необходимые для реального шифрования? Мой код был написан после некоторого примера кода, который сказал, чтобы шифровать пароль. – tom

+1

@tom: для паролей вы, вероятно, не должны * использовать обратимое шифрование. Даже хеширование не является само по себе - вы должны хотя бы солить хэш, а также выбрать соответствующий алгоритм хэширования. (Пройдите поиск криптографии с солью для получения более подробной информации.) –

+0

Большое спасибо за объяснение. – tom

1

Я не знаю, какой класс Base64 вы используете, но я возьмусь за него из Apache Commons. Вы делаете это:

String hash = Base64.encodeBase64(raw).toString(); 

Который называет toString метод на любой случайный массив байтов возвращается из метода Base64.encodeBase64(). Вот почему ваш результат случайный каждый раз, вы просто возвращаете ссылку на объект как строку. Попробуйте вместо этого:

String hash = Base64.encodeBase64String(raw); 

EDIT

Как отмечалось в другом посте, преобразование непосредственно в строку, вероятно, плохая идея. Я немного изменил свой ответ, чтобы отразить это.

Смежные вопросы