От чего на самом деле защищает хеширование пароля
Хеширование паролей — не магия. Это механизм ограничения ущерба на тот день, когда ваша таблица пользователей утечет.
Содержание
- Короткая версия
- Что такое хеш пароля
- От чего защищает хеширование
- 1. Немедленное раскрытие паролей после взлома базы данных
- 2. Массовые атаки на всю вашу пользовательскую базу
- 3. Быстрый офлайн-подбор
- От чего хеширование не защищает
- 1. Фишинг
- 2. Credential stuffing
- 3. Пароли, попавшие в логи или аналитику
- 4. Плохая безопасность сессий
- 5. Слабый сброс пароля и восстановление аккаунта
- Выбор алгоритма: что использовать сейчас
- Cost factors нельзя настроить один раз и забыть
- Peppers: полезны, но не замена
- Операционный чек-лист
- Честная ментальная модель
Короткая версия
Хеширование пароля защищает пользователей, когда ваша база данных паролей украдена.
Это его главная задача. Не единственная деталь, не вся модель безопасности, но центральная причина, по которой мы хешируем пароли, а не храним их напрямую.
Правильно хешированный пароль трудно обратить. Если злоумышленник получает копию вашей таблицы пользователей, он не должен сразу узнать, что пароль Алисы — Spring2026!. Вместо этого он получает сохраненный хеш, проверка которого против догадок требует времени, денег и оборудования.
Это различие важно. Хеширование паролей не предназначено для того, чтобы само по себе сделать вход безопасным. Оно не останавливает фишинг. Оно не мешает кому-то пробовать утекшие пароли через вашу форму входа. Оно не защищает session cookie после входа. Оно выигрывает время и снижает ущерб после очень конкретного сбоя: хранилище ваших проверочных данных паролей становится доступным посторонним.
Если вы понимаете эту границу, вы будете принимать более правильные решения об алгоритмах, рабочих факторах, сбросах, логировании и реагировании на инциденты.
Что такое хеш пароля
Хеш пароля — это результат применения односторонней функции к паролю, обычно с уникальной солью и намеренно медленным алгоритмом хеширования паролей.
Когда пользователь создает аккаунт, система должна примерно сделать следующее:
- Получить пароль по HTTPS.
- Сгенерировать случайную уникальную соль.
- Пропустить пароль и соль через функцию хеширования паролей, такую как Argon2id, bcrypt, scrypt или PBKDF2.
- Сохранить имя алгоритма, параметры, соль и получившийся хеш.
- Удалить исходный пароль.
Когда пользователь позже входит в систему, она повторяет тот же процесс хеширования с введенным паролем и сохраненными параметрами. Если получившийся хеш совпадает с сохраненным хешем, вход успешен.
Важная часть: приложению не нужно знать исходный пароль. Ему нужно только проверить, что введенный пароль дает ожидаемый результат.
Именно поэтому хранение паролей с обратимым шифрованием обычно является неправильной моделью. Если ваше приложение может расшифровать каждый пароль, то любой, кто украдет ключ расшифрования, сможет сделать то же самое. Пароли обычно должны быть необратимыми для проверки в обратную сторону, а не просто скрытыми.
От чего защищает хеширование
1. Немедленное раскрытие паролей после взлома базы данных
Если злоумышленник крадет базу данных с паролями в открытом виде, ущерб наступает мгновенно. Каждый пароль раскрыт. Пользователи оказываются под угрозой не только на вашем сайте, но и везде, где они повторно использовали этот пароль.
Если база данных содержит хорошо хешированные пароли, злоумышленнику нужно проделать больше работы. Он должен угадывать кандидаты в пароли, хешировать каждую догадку с правильной солью и параметрами, а затем сравнивать результат.
Для слабых паролей это все еще может быть быстро. Для сильных уникальных паролей это может быть практически неосуществимо.
Хеширование превращает катастрофическое раскрытие в гонку: успеют ли пользователи сбросить пароли и сможете ли вы сдержать инцидент до того, как злоумышленники взломают многие из них?
Это не идеально. Это все равно утечка. Но это значительно лучший режим отказа.
2. Массовые атаки на всю вашу пользовательскую базу
Соли — ключевая часть хранения паролей, потому что они не дают злоумышленникам эффективно атаковать многих пользователей сразу с помощью заранее вычисленных таблиц.
Соль не является секретом. Она хранится рядом с хешем. Ее задача — уникальность.
Если два пользователя выбирают один и тот же пароль, уникальные соли гарантируют, что их сохраненные хеши будут отличаться. Это не позволяет злоумышленникам с первого взгляда увидеть, что многие пользователи используют один и тот же пароль. Это также предотвращает классические атаки с rainbow table, где злоумышленники используют огромные заранее вычисленные списки соответствий пароль-хеш.
Без солей один взломанный хеш может раскрыть каждого пользователя с тем же паролем. С солями каждую догадку о пароле нужно проверять отдельно для каждого пользователя.
3. Быстрый офлайн-подбор
После того как у злоумышленников есть база данных паролей, они могут подбирать их офлайн. Это означает, что ваши ограничения частоты входа, CAPTCHA, блокировка IP и мониторинг больше не имеют значения. Злоумышленник может проверять догадки на своем собственном оборудовании.
Именно здесь важен выбор алгоритма.
Хеши общего назначения, такие как SHA-256 и SHA-512, спроектированы быстрыми. Это хорошо для целостности файлов и цифровых подписей. Это плохо для хранения паролей.
Алгоритмы хеширования паролей спроектированы медленными, настраиваемыми и иногда memory-hard. Argon2id, bcrypt, scrypt и PBKDF2 позволяют настраивать параметры стоимости так, чтобы каждая догадка занимала ощутимое время.
Argon2id широко рекомендуют для новых систем, потому что его можно настроить так, чтобы требовались и CPU-время, и память, что делает крупномасштабный взлом на GPU дороже. bcrypt остается распространенным и приемлемым при хорошей настройке, хотя у него есть ограничения, например в обработке длины пароля. PBKDF2 все еще используется в некоторых средах, ориентированных на соответствие требованиям, особенно там, где нужны компоненты с FIPS-валидацией.
Принцип прост: сделать легитимные входы приемлемо быстрыми, одновременно делая миллиарды догадок дорогими.
От чего хеширование не защищает
1. Фишинг
Если пользователь вводит пароль на поддельной странице входа, хеширование на вашем сервере не поможет. Злоумышленник получает пароль еще до того, как ваша система его увидит.
Защиты здесь другие: многофакторная аутентификация, passkeys, обучение пользователей, гигиена доменов, фишинг-устойчивая аутентификация и аккуратные процессы сброса пароля.
Хеширование паролей — это резервная защита для сохраненных секретов. Это не защита от того, что пользователей обманом заставляют отдать эти секреты.
2. Credential stuffing
Credential stuffing происходит, когда злоумышленники берут пары имени пользователя и пароля, утекшие из одного сервиса, и пробуют их в другом.
Ваши хеши паролей могут быть отличными, и credential stuffing все равно может сработать, если пользователи повторно используют пароли.
Это онлайн-атака на вашу форму входа, а не офлайн-атака на вашу базу данных. Вам нужны ограничения частоты, обнаружение аномалий, проверки по утекшим паролям, MFA и разумные политики блокировки, которые не создают простых возможностей для denial-of-service.
Та же практическая логика применима к любой открытой форме. Если вы пересматриваете поверхность аутентификации, стоит прочитать о том, почему ваша контактная форма — ваша главная спам-уязвимость; механика отличается, но урок похож: публичным вводам нужны меры против злоупотреблений, а не только чистый backend-код.
3. Пароли, попавшие в логи или аналитику
Хеширование помогает только если пароль в открытом виде быстро удаляется и нигде больше не копируется.
Типичные ошибки включают:
- Логирование полных тел запросов при неудачных попытках входа.
- Отправку паролей в инструменты мониторинга ошибок.
- Захват полей пароля в продуктах session replay.
- Включение учетных данных в URL во время плохо спроектированных процессов сброса или миграции.
- Хранение временных паролей в открытом виде во время импортов.
Эти ошибки полностью обходят хеширование паролей. Если открытый текст попадает в логи, резервные копии, хранилища данных или сторонние инструменты, ваша хеш-функция не имеет значения.
Относитесь к полям пароля как к токсичным данным. Редактируйте их до логирования. Исключайте их из аналитики. Не допускайте их в URL. Ограничьте доступ к production-трассировкам.
4. Плохая безопасность сессий
После входа браузер пользователя обычно получает session cookie или токен. Если этот токен украден, злоумышленнику может вообще не понадобиться пароль.
Хеширование паролей не защищает от cross-site scripting, небезопасных cookies, фиксации сессии, слабой генерации токенов или чрезмерно долгого времени жизни сессии.
Session cookies заслуживают отдельной проверки: HttpOnly, Secure, подходящий SameSite, короткоживущие сессии для высокорисковых действий и серверная инвалидизация при смене пароля. Более широкий ландшафт приватности и браузеров тоже продолжает меняться, как описано в статье что изменилось для cookies в 2026 году.
5. Слабый сброс пароля и восстановление аккаунта
Многие захваты аккаунтов начинаются не с пароля. Они начинаются с процесса сброса.
Если токены сброса предсказуемы, живут слишком долго, утекают через referrer headers или отправляются на скомпрометированные почтовые ящики, хеширование паролей вас не спасет.
Используйте reset tokens с высокой энтропией, короткими окнами действия, одноразовым использованием и понятными уведомлениями пользователей. Поскольку email часто является каналом восстановления, базовая аутентификация домена тоже важна. Если ваша команда воспринимает DNS-записи как загадочный ритуал, начните с дружелюбного для разработчиков обзора MX, SPF, DKIM и DMARC.
Выбор алгоритма: что использовать сейчас
Для новых приложений используйте Argon2id, если ваша платформа хорошо его поддерживает. Он победил в Password Hashing Competition и спроектирован для хранения паролей, включая устойчивость к взлому с интенсивным использованием GPU.
Разумная современная иерархия выглядит так:
- Argon2id для новых систем, где он доступен.
- bcrypt когда Argon2id непрактичен, а поддержка bcrypt зрелая.
- scrypt когда хорошо поддерживается memory-hard конфигурация.
- PBKDF2 где это требуется ограничениями платформы или compliance.
Избегайте простого SHA-256, SHA-512, MD5 или самодельных комбинаций вроде sha256(password + salt). Быстрые хеши не являются функциями хранения паролей. Хитрые пользовательские конструкции обычно хуже скучных стандартных.
Также не изобретайте собственную политику паролей вокруг мелочей алгоритмов. Пользователям не помогает контрольный список из 12 правил состава пароля, если он подталкивает их к предсказуемым шаблонам. Более длинные уникальные пароли, менеджеры паролей, проверка по утекшим паролям и MFA обычно важнее.
Cost factors нельзя настроить один раз и забыть
У хеширования паролей есть параметры. У Argon2id есть память, итерации и параллелизм. У bcrypt есть cost factor. У PBKDF2 есть число итераций.
Эти значения нужно выбирать на основе вашей production-среды. Слишком низкие — и злоумышленники подбирают дешево. Слишком высокие — и ваша система входа становится медленной или уязвимой к denial-of-service.
Практическая цель часто находится в диапазоне от десятков до нескольких сотен миллисекунд на проверку пароля на ваших фактических серверах, в зависимости от трафика и риска. Высокозащищенные системы могут выбрать больше. Системам потребительского масштаба может понадобиться тщательное планирование емкости.
Не копируйте cost factor из пятилетней статьи в блоге. Оборудование меняется. Библиотеки меняются. Ваш трафик меняется.
Периодически пересматривайте параметры и планируйте повторное хеширование. Распространенный шаблон — хранить алгоритм и параметры вместе с каждым хешем. При успешном входе, если сохраненные параметры устарели, повторно хешировать введенный пароль с более новой конфигурацией и обновлять запись.
Peppers: полезны, но не замена
Pepper — это секретное значение, добавляемое в процесс хеширования пароля и хранящееся отдельно от базы данных, часто в secrets manager или hardware security module.
В отличие от соли, pepper должен оставаться секретным.
Peppers могут снизить ущерб, если база данных утечет, а секреты приложения — нет. Они наиболее полезны в зрелых средах с хорошим управлением ключами. Они менее полезны, если тот же злоумышленник может украсть и базу данных, и конфигурацию приложения.
Если вы используете pepper, тщательно планируйте ротацию. Его ротация может потребовать, чтобы пользователи снова вошли в систему или сбросили пароли, в зависимости от дизайна. Pepper — это дополнительный слой, а не причина ослаблять базовые настройки хеша.
Операционный чек-лист
Если вы отвечаете за реальную систему, практический чек-лист короткий:
- Храните пароли только с помощью стандартного алгоритма хеширования паролей.
- Используйте уникальную случайную соль для каждого пароля.
- Предпочитайте Argon2id для новых проектов.
- Настраивайте параметры стоимости на железе, похожем на production.
- Храните алгоритм и параметры вместе с каждым хешем.
- Повторно хешируйте при входе, когда параметры устаревают.
- Никогда не логируйте пароли и не отправляйте их в инструменты аналитики.
- Используйте TLS везде, где передаются учетные данные.
- Добавляйте MFA или passkeys там, где риск это оправдывает.
- Защищайте процессы сброса так же серьезно, как процессы входа.
- Имейте план инцидента для принудительных сбросов и уведомления пользователей.
Хеширование паролей не выглядит эффектно. Это инфраструктурная сантехника. Но именно такая сантехника определяет, станет ли утечка болезненным инцидентом или катастрофой для всех пользователей.
<!-- tool-cta:start -->
💡 Попробуйте: Посмотрите, как один и тот же ввод сопоставляется с разными алгоритмами с помощью Hash Generator, который наглядно показывает разницу между быстрыми хешами и хешами уровня паролей.
<!-- tool-cta:end -->
Честная ментальная модель
Лучший способ думать о хешировании паролей таков:
Хеширование не защищает пароль, пока пользователь его вводит. Оно не защищает аккаунт после того, как пользователь вошел. Оно не защищает пользователей, которые повторно используют пароли по всему вебу.
Оно защищает сохраненный verifier.
Это звучит узко, но это чрезвычайно важно. Базы данных утекают. Резервные копии утекают. Staging-системы копируются. Вендоры получают доступ, которого у них не должно быть. Старые экспорты лежат в object storage дольше, чем кто-либо помнит.
Когда это происходит, дизайн вашего хранения паролей становится разницей между тем, что злоумышленники получают пароли, и тем, что злоумышленники получают дорогую задачу угадывания.
Вот от чего на самом деле защищает хеширование пароля.