Руководства по безопасности
Как безопасно хранить пароли — правильный способ хеширования и соли
Как следует хранить пароли пользователей? Почему открытый текст, шифрование и сырые хеши все проваливаются, что делает соль для каждого пользователя и настоящий ответ — медленный хеш (bcrypt/Argon2/scrypt): как выбрать его, настроить и перенести существующую систему. Защитно и с упором на разработчика, без шагов атаки.
«Как именно хранить пароли пользователей в базе данных?» — каждый создатель однажды натыкается на этот вопрос. Ответ ясен. Вот безопасный способ их хранить, по порядку, без шагов атаки.
Почему открытый текст, шифрование и сырые хеши все проваливаются
Предположим, что база данных однажды утечёт. Когда это случится, ущерб сильно различается по методу хранения.
- Открытый текст: каждый пароль раскрыт в тот же миг, как он утёк. Хуже того, переиспользование паролей сцепляет утечку с другими сервисами пользователя. Худший случай.
- Шифрование (обратимое): ключ возвращает всё назад — поэтому если ключ утечёт вместе с ним, вы снова в открытом тексте. Пароль никогда не нужно читать обратно, так что обратимость ничего вам не даёт.
- Сырой хеш (MD5/SHA-256): быстрый хеш позволяет атакующему быстро проверять догадки. Распространённые пароли падают перед радужными таблицами и перебором.
«Четыре стадии» к безопасности
Быстрее всего понять это как добавление по одному исправлению к слабому методу.
Ключевое понимание: соль и медленный хеш делают разную работу. Соль побеждает предвычисление (радужные таблицы) и массовый взлом за счёт переиспользования. Медленный хеш роняет перебор до непрактичной скорости. Вам нужны оба, прежде чем это станет безопасным (→ что такое хеширование).
На практике: что делать сейчас
Используйте Argon2id (или bcrypt)
Для новых систем сделайте Argon2id первым выбором — он может требовать ещё и память, что сопротивляется перебору на GPU. Если вы предпочитаете проверенную в бою реализацию, bcrypt на практике более чем достаточно. Используйте реализацию из стандартной библиотеки как есть для любого из них.
Пусть соль будет автоматической
bcrypt/Argon2 генерируют соль для каждого пользователя и встраивают её внутрь строки хеша. Вы не держите отдельный столбец для соли. Самодельный MD5(salt + password) — классика того, чего делать не надо.
Настройте стоимость под вашу среду
Задайте фактор стоимости bcrypt или память/итерации/параллелизм Argon2 настолько высоко, насколько можно, пока легитимный вход всё ещё ощущается мгновенным. Серверы становятся быстрее — но и атакующие тоже; пересматривайте и повышайте это ежегодно.
Проверяйте стандартной функцией сравнения
При входе сопоставляйте ввод с сохранённым хешем функцией проверки из библиотеки (большинство используют безопасное по времени сравнение с постоянным временем). Не пишите своё сравнение строк.
Переносите слабые хеши перехешированием при входе
Если вы уже храните MD5/SHA-256, в тот миг, когда пользователь успешно входит, перехешируйте новой схемой и сохраните. Для тех, кто не входил, можно временно повысить, обернув существующий хеш в bcrypt (слоёный хеш).
Типичные ошибки vs правильная реализация
Типичная ошибка
- Шифровать пароли для хранения (ключ утёк → конец)
- Хранить
MD5(password)илиSHA-256(password)напрямую - Использовать одну общую соль для всех пользователей
- Самодельный
hash(salt + password)
Правильная реализация
- Односторонний хеш с Argon2id / bcrypt
- Соль для каждого пользователя (библиотека добавляет её автоматически)
- Стоимость настолько высока, насколько комфортно, повышается периодически
- Использовать стандартные функции хеширования/проверки как есть
Взгляд этого сайта: хранение паролей — место, где надо ехать на скучном, проверенном ответе
Хранение паролей — это не место для творчества. Ехать на проверенных миром стандартных реализациях Argon2/bcrypt — самое безопасное и самое простое в эксплуатации. Наша позиция: не новаторствуйте здесь. Тратьте усилия на снижение зависимости от паролей вообще — на тщательную многофакторную аутентификацию (MFA) и со временем на переход к passkey (без пароля). Даже сильнейший хеш не спасёт слабый, переиспользованный пароль.
Читать дальше
- Глоссарий: что такое хеширование паролей / что такое соль
- Основы: правильное хранение паролей (со стороны пользователя) / выбор менеджера паролей
- Защита: правильный выбор MFA (снизить зависимость от паролей)
- Глоссарий: что такое passkey (движение к беспарольности)
FAQ
QМожет, просто зашифровать пароли для хранения?
Нет — шифрование это неправильный инструмент. Шифрование обратимо при наличии ключа, поэтому, если ключ утечёт, все пароли снова станут открытым текстом. Пароль никогда не нужно читать обратно, даже вам, поэтому необратимый «хеш» — правильный ответ. Но сырого хеша недостаточно; сочетайте соль для каждого пользователя с медленным хешем (bcrypt/Argon2).
Qbcrypt или Argon2 — что использовать?
Для новой разработки Argon2 (особенно Argon2id) — первый выбор: он позволяет настраивать и память, и вычисления, что хорошо сопротивляется перебору на GPU. Если вы цените давно проверенную в бою реализацию, bcrypt по-прежнему вполне практичен. Ключевой момент с любым из них — использовать реализацию из стандартной библиотеки как есть и не изобретать своё.
QЯ уже храню пароли в MD5/SHA-256. Как перенести?
Массово обратно в открытый текст не преобразовать (в этом и смысл), поэтому переносите при входе. В тот миг, когда пользователь успешно входит, перехешируйте правильный пароль, который он только что ввёл, новой схемой (например, Argon2id) и сохраните. Для тех, кто не входил, можно временно повысить, обернув существующий хеш в bcrypt (слоёный хеш).