- Хэширование пароля на Java
- 1. Обзор
- 2. Что такое хеширование?
- 3. Не рекомендуется: MD5
- 4. Не рекомендуется: SHA-512
- 4.1. Почему SHA-512?
- 4.2. Реализация на Java
- 4.3. Получение соли
- 4.4. Почему Это Не Рекомендуется?
- 5. PBKDF2, BCrypt и SCrypt
- 5.1. Почему Они Рекомендуются?
- 5.2. Реализация PBKDF2 в Java
- 5.3. Реализация BCrypt и SCrypt в Java
- 6. Хэширование Паролей С Помощью Spring Security
- 7. Заключение
Хэширование пароля на Java
Узнайте, как безопасно хэшировать пароли на Java и почему MD5 настолько небезопасен.
1. Обзор
В этом уроке мы обсудим важность хэширования паролей.
Мы быстро рассмотрим, что это такое, почему это важно, а также некоторые безопасные и небезопасные способы выполнения этого на Java.
2. Что такое хеширование?
Хэширование – это процесс генерации строки или хэша из заданного сообщения с использованием математической функции, известной как криптографическая хэш-функция .
Хотя существует несколько хэш-функций, те, которые предназначены для хеширования паролей, должны обладать четырьмя основными свойствами для обеспечения безопасности:
- Это должно быть детерминированным : одно и то же сообщение, обработанное одной и той же хэш-функцией, должно всегда давать один и тот же хэш
- Это не обратимо : нецелесообразно генерировать сообщение из его хэша
- Он имеет высокую энтропию : небольшое изменение в сообщении должно привести к совершенно другому хэшу
- И он сопротивляется столкновениям : два разных сообщения не должны создавать один и тот же хэш
Хэш-функция, обладающая всеми четырьмя свойствами, является надежным кандидатом для хэширования паролей, поскольку вместе они значительно повышают сложность обратной разработки пароля из хэша.
Кроме того, однако, функции хэширования паролей должны быть медленными . Быстрый алгоритм помог бы атакам грубой силы , в которых хакер попытается угадать пароль, хэшируя и сравнивая миллиарды ( или триллионы ) потенциальных паролей в секунду.
Некоторые отличные хэш-функции, соответствующие всем этим критериям, – это PBKDF2, BCrypt, и SCrypt. Но сначала давайте посмотрим на некоторые старые алгоритмы и почему они больше не рекомендуются
3. Не рекомендуется: MD5
Наша первая хэш-функция-это алгоритм дайджеста сообщений MD5, разработанный еще в 1992 году.
Java MessageDigest упрощает вычисление и все еще может быть полезен в других обстоятельствах.
Однако за последние несколько лет было обнаружено, что MD5 не выполняет четвертое свойство хэширования паролей в связи с тем, что стало вычислительно легко генерировать конфликты. В довершение всего, MD5-это быстрый алгоритм, и поэтому он бесполезен против атак грубой силы.
Из-за этого MD5 не рекомендуется.
4. Не рекомендуется: SHA-512
Далее мы рассмотрим SHA-512, который является частью семейства безопасных алгоритмов хэширования, семейства, которое началось с SHA-0 еще в 1993 году.
4.1. Почему SHA-512?
По мере увеличения мощности компьютеров и обнаружения новых уязвимостей исследователи выводят новые версии SHA. Более новые версии имеют постепенно увеличивающуюся длину, или иногда исследователи публикуют новую версию базового алгоритма.
SHA-512 представляет собой самый длинный ключ в третьем поколении алгоритма.
В то время как в настоящее время существуют более безопасные версии SHA , SHA-512 является самой сильной версией, реализованной в Java .
4.2. Реализация на Java
Теперь давайте рассмотрим реализацию алгоритма хэширования SHA-512 в Java.
Во-первых, мы должны понять концепцию соли . Проще говоря, это случайная последовательность, которая генерируется для каждого нового хэша .
Вводя эту случайность, мы увеличиваем энтропию хэша и защищаем нашу базу данных от предварительно составленных списков хэшей , известных как радужные таблицы .
Затем наша новая хэш-функция становится примерно:
4.3. Получение соли
Чтобы ввести соль, мы будем использовать класс SecureRandom из java.security :
SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; random.nextBytes(salt);
Затем мы будем использовать класс MessageDigest для настройки хэш-функции SHA-512 с помощью нашей соли:
MessageDigest md = MessageDigest.getInstance("SHA-512"); md.update(salt);
И с учетом этого мы теперь можем использовать метод digest для создания нашего хэшированного пароля:
byte[] hashedPassword = md.digest(passwordToHash.getBytes(StandardCharsets.UTF_8));
4.4. Почему Это Не Рекомендуется?
При использовании с солью SHA512 по-прежнему является справедливым вариантом , , но существуют более сильные и медленные варианты .
Кроме того, остальные опции, которые мы рассмотрим, имеют важную особенность: настраиваемую силу.
5. PBKDF2, BCrypt и SCrypt
PBKDF2, BCrypt и SCrypt-это три рекомендуемых алгоритма.
5.1. Почему Они Рекомендуются?
Каждый из них медленный, и у каждого есть блестящая особенность-настраиваемая сила.
Это означает, что по мере увеличения мощности компьютеров мы можем замедлить алгоритм, изменив входные данные.
5.2. Реализация PBKDF2 в Java
Теперь соли являются фундаментальным принципом хэширования паролей , и поэтому он нам тоже нужен для PBKDF2:
SecureRandom random = new SecureRandom(); byte[] salt = new byte[16]; random.nextBytes(salt);
Затем мы создадим PBEKeySpec и SecretKeyFactory , которые мы создадим с помощью алгоритма PBKDF2WithHmacSHA1 :
KeySpec spec = new PBEKeySpec(password.toCharArray(), salt, 65536, 128); SecretKeyFactory factory = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA1");
Третий параметр ( 65536 ) фактически является параметром прочности. Он указывает, на сколько итераций выполняется этот алгоритм, увеличивая время, необходимое для создания хэша.
Наконец, мы можем использовать наш SecretKeyFactory для генерации хэша:
byte[] hash = factory.generateSecret(spec).getEncoded();
5.3. Реализация BCrypt и SCrypt в Java
Итак, оказывается, что BCrypt и поддержка SCrypt еще не поставляются с Java , хотя некоторые библиотеки Java поддерживают их.
Одна из таких библиотек-Spring Security.
6. Хэширование Паролей С Помощью Spring Security
Хотя Java изначально поддерживает алгоритмы хэширования PBKDF2 и SHA, она не поддерживает алгоритмы BCrypt и SCrypt.
К счастью для нас, Spring Security поставляется с поддержкой всех этих рекомендуемых алгоритмов через интерфейс PasswordEncoder :
- MessageDigestPasswordEncoder дает нам MD5 и SHA-512
- Pbkdf2PasswordEncoder дает нам PBKDF2
- BCryptPasswordEncoder дает нам BCrypt, и
- Шифратор паролей SCrypt дает нам скрипт
Кодеры паролей для PBKDF2, BCrypt и SCrypt поставляются с поддержкой настройки желаемой силы хэша пароля.
Мы можем использовать эти кодеры напрямую, даже не имея приложения, основанного на безопасности Spring. Или, если мы защищаем наш сайт с помощью Spring Security, мы можем настроить нужный кодировщик паролей с помощью DSL или с помощью внедрения зависимостей .
И, в отличие от наших примеров выше, эти алгоритмы шифрования будут генерировать соль для нас внутри . Алгоритм сохраняет соль в выходном хэше для последующего использования при проверке пароля.
7. Заключение
Итак, мы глубоко погрузились в хэширование паролей, исследуя концепцию и ее использование.
И мы рассмотрели некоторые исторические хэш-функции, а также некоторые реализованные в настоящее время, прежде чем кодировать их на Java.
Наконец, мы увидели, что Spring Security поставляется со своими классами шифрования паролей, реализующими множество различных хэш-функций.