Безопасное хранение паролей: руководство для разработчиков

Введение
Пароли — высокочувствительная информация. Ошибка в обращении с ними приводит к серьёзным утечкам данных и компрометации пользователей. В этом руководстве изложены практики, которые помогут минимизировать риск: варианты архитектурных решений, криптографические рекомендации, операционные процедуры и тесты приёмки.
Определения в одну строку
- Хеш — односторонняя функция, дающая фиксированный выход для входных данных.
- Соль — случайная строка, добавляемая к паролю перед хешированием для защиты от заранее вычисленных таблиц.
- PBKDF2 — криптографическая функция вывода ключа, специально предназначенная для безопасного хеширования паролей.
- OAuth — протокол авторизации, позволяющий сторонним провайдерам управлять учётными данными пользователей.
Почему это важно
Большинство атак, связанных с паролями, происходят после получения доступа к серверу или базе данных. Даже хорошо защищённый сервер важно рассматривать как потенциально скомпрометированный: реализуйте «управление ущербом», чтобы минимизировать последствия, если злоумышленник всё же попадёт внутрь.
Основные рекомендации
1. Используйте OAuth, если есть такая возможность
Лучший способ работать с паролями — не работать с ними вовсе. OAuth и сторонняя аутентификация (Google, Apple, Facebook и т.д.) избавляют вас от хранения и обработки паролей. Даже при абсолютной компрометации вашего сервера у злоумышленника не будет паролей пользователей, лишь токены и данные провайдера.
Когда стоит выбрать OAuth
- Если пользователи ожидают удобного входа через сторонние сервисы.
- Если вы хотите сократить область ответственности за безопасность учётных данных.
Когда OAuth не подходит
- Если у вас есть регуляторные требования, обязывающие контролировать учётные записи.
- Если сервис должен работать в автономном окружении без внешних провайдеров.
2. Никогда не храните пароли в открытом виде
«Открытый вид» или plaintext означает, что кто‑то с доступом к диску может прочитать пароли напрямую. Это включает базы данных, журналы и резервные копии. Всегда храните только проверяемый результат — хеш.
Классическая ошибка: отправлять и сохранять пароль в БД как строку. Вместо этого сохраняйте хеш и дополнительные метаданные (соль, параметры алгоритма, итерации).
Пример: хеш SHA256 для слова password (пример для иллюстрации) — это однонаправленная строка, которую нельзя «раскодировать», но можно подбором подобрать вход.
3. Добавляйте соль к каждому паролю
Проблема обычных хешей — радужные таблицы (rainbow tables). Это предвычисленные пары «пароль→хеш» для огромного множества вариантов. Радужные таблицы экономят время за счёт хранения больших объёмов данных.

Решение — соль: уникальная случайная строка для каждой записи. Вместо хеширования лишь password вы хешируете password + . Соль хранится рядом с хешем в БД в открытом виде. Соль исключает возможность эффективного использования одной общей радужной таблицы для многих пользователей.
Правила по соли
- Генерируйте уникальную соль для каждого пароля.
- Соль не обязана быть секретной, но должна быть достаточной длины (например, 16+ байт случайных данных).
- Не переиспользуйте соль между пользователями.
4. Используйте алгоритмы, созданные для паролей
Обычные общие хеши (SHA256, SHA1, MD5) были спроектированы для скорости и предназначены для целостности данных, а не для хранения паролей. Быстрый хеш — это преимущество для атакующего при подборе паролей.
Используйте KDF (Key Derivation Function): PBKDF2, bcrypt, scrypt или Argon2. Эти алгоритмы специально сделаны «медленнее» и могут быть настроены по ресурсной стоимости (итерации, память, параллелизм), чтобы усложнить массовый подбор.
Краткие определения в одну строку
- PBKDF2 — итеративная KDF на основе HMAC, конфигурируется по числу итераций.
- bcrypt — устойчива к атаке по памяти и прослужила долго в практике.
- scrypt — усложняет атаки за счёт использования памяти.
- Argon2 — современный победитель алгоритмических соревнований, хороший выбор, если доступен.
Практические советы
- Если используете PBKDF2 — выставьте высокое число итераций, соизмеримое с нагрузкой вашей системы.
- Для веб‑клиента можно хешировать на клиентской стороне для сокращения области, где встречается plaintext. Но это не заменяет серверного KDF. Клиентский хеш защищает канал и часть сервера от моментальных утечек.
- Не используйте MD5 и SHA1 для хранения паролей — они устарели.
5. Требования к паролям и UX
Длина важнее сложности символов. Длина делает пространство поиска экспоненциально больше. Рекомендуемые минимумы:
- Минимум 8–12 символов для базовых сервисов.
- Рассмотрите увеличение до 12+ для чувствительных систем.
- Поощряйте фразы (passphrases) длиной 20+ символов — они удобнее и безопаснее.
UX-принципы
- Показывайте индикатор силы пароля, опираясь на длину и уникальность.
- Не требуйте сложных правил с символами, если это ухудшает удобство и приводит к повторному использованию паролей.
- Поддерживайте менеджеры паролей и не запрещайте вставку.
Операционные и инфраструктурные меры
- Всегда используйте HTTPS. Никогда не передавайте пароли по HTTP.
- Логи: не сохраняйте пароли, даже временные, в логах ошибок и запросов.
- Ограничьте доступ к БД и введите аудит доступа. Принцип наименьших привилегий.
- Шифрование на уровне диска полезно, но не заменяет правильно хешированные пароли.
- Регулярно обновляйте библиотеки криптографии.
Что делать при компрометации
Краткий план реагирования:
- Изолировать систему и остановить доступы.
- Оценить объём утечки и какого типа данные попали в руки.
- Сбросить сеансовые токены и потребовать сброс паролей при входе.
- Сообщить пользователям и регуляторам согласно требованиям GDPR/законодательству.
- Провести пост‑инцидентный разбор и закрыть уязвимости.
Критерии приёмки инцидента
- Все скомпрометированные учётные записи переведены в состояние «требуется сброс пароля».
- Сеансовые и долгоживущие токены отозваны.
- Проведён аудит доступа и подтверждён источник компрометации.
Практическое руководство: пошаговая методика внедрения безопасного хранения паролей
- Решите, нужен ли вам собственный парольный механизм. Если нет — используйте OAuth.
- Если нужен — выберите KDF (Argon2 > scrypt > bcrypt > PBKDF2 при прочих равных).
- Определите параметры: соль (16+ байт), итерации/память/параллелизм согласно аппаратным возможностям.
- На уровне клиента выполняйте валидацию и, при желании, предварительный хеш (но не вместо серверного KDF).
- Храните в БД структуру: {user_id, hash, salt, algorithm, params, created_at}.
- Реализуйте механизм регулярного пересчёта хешей при повышении параметров (upgrade path).
- Напишите тесты и runbook на случай утечки.
Шаблон записи в базе (пример JSON для колонки):
{
"algo": "pbkdf2-sha256",
"iterations": 200000,
"salt": "1D75BCA3...",
"hash": "6b3a55e0...",
"created_at": "2025-01-15T12:34:56Z"
}Сравнение популярных подходов
| Алгоритм | Преимущества | Недостатки |
|---|---|---|
| PBKDF2 | Широко доступен, прост в настройке | Требует много итераций, слаб по памяти |
| bcrypt | Испытан временем, удобен | Ограничение длины пароля в старых реализациях |
| scrypt | Указывает потребление памяти, хорош против ASIC | Реже в стандартных библиотеках |
| Argon2 | Современный, гибкий по памяти и времени | Может быть недоступен в старых средах |
Важно: выбор зависит от потребностей и инфраструктуры. Если доступен Argon2 — он хороший выбор.
Когда эти меры не спасут
- Если у злоумышленника есть доступ к устройству пользователя (кейлоггеры, вредоносное ПО), то никакие серверные меры не помогут.
- Если пользователь применяет один и тот же пароль в сотнях сервисов, утечка одного пароля опасна.
- Если секреты хранятся в репозитории кода или в логах — это человеческая ошибка, требующая процесса и ревью.
Тесты и критерии приёмки
Критерии приёмки системы хранения паролей:
- Пароли не хранятся в открытом виде нигде в системе.
- Каждый хеш сопровождается уникальной солью.
- Используется KDF с параметрами, документированными и тестируемыми.
- Есть тесты на совместимость (вход пользователя → ожидаемый алгоритм и параметры используются).
- Есть автоматические тесты производительности KDF для мониторинга деградации.
Тест-кейсы
- Попытка логина с корректным паролем проходит.
- Попытка логина с некорректным паролем не даёт подсказок об истинной причине.
- При смене параметров KDF существующие хеши остаются валидны, и при успешном входе пересчитываются под новые параметры.
Роль‑базированные чеклисты
Разработчик
- Реализовать обработку пароля только в памяти.
- Не логировать пароли.
- Записать миграцию схемы для хранения параметров KDF.
Оператор/DevOps
- Ограничить доступ к БД и журналам.
- Настроить мониторинг для необычной активности чтения БД.
- Хранить резервные копии в зашифрованном виде и с контролем доступа.
Команда безопасности
- Регулярно пересматривать параметры KDF.
- Проводить тесты утечки паролей в тестовой среде.
- Составить и обновлять runbook реагирования на утечку.
Runbook реагирования на утечку паролей
- Оповестить команду инцидента.
- Снять систему с внешнего доступа при необходимости.
- Выключить незавершённые процессы миграции паролей.
- Отключить старые ключи и отозвать долгоживущие токены.
- Уведомить пользователей с инструкцией смены пароля и информацией о сроках и мерах.
- После восстановления — провести ретроспективу и зафиксировать корректирующие меры.
Примеры кода и сниппеты
Пример принципа: сначала соль, затем KDF
# Псевдокод
salt = secure_random(16)
hash = pbkdf2(password, salt, iterations=200000)
store({salt: salt, hash: hash, algo: 'pbkdf2', iter: 200000})Необходимо хранить также версию алгоритма, чтобы при обновлении параметров у вас была возможность постепенно пересчитывать старые хеши.
Ментальные модели и эвристики
- «Защита по слою»: не полагайтесь на один барьер. Хеширование, соль, доступ по ролям, аудит, HTTPS — всё вместе.
- «Минимизация области риска»: уменьшайте количество систем, которые имеют дело с plaintext.
- «Управление ущербом»: закладывайте шаги по откату и отзыву токенов заранее.
Полезные шаблоны и таблицы
Шаблон для оценки выбора алгоритма
| Критерий | Argon2 | scrypt | bcrypt | PBKDF2 |
|---|---|---|---|---|
| Защита от аппаратного ускорения | высокий | высокий | средний | низкий |
| Требуемые библиотеки на большинстве платформ | средне | средне | высоко | очень высоко |
| Простота настройки | средне | средне | высокая | высокая |
Мини‑чеклист развертывания
- Выбран алгоритм хранения паролей и задокументирован.
- Генерация соли реализована и тестирована.
- Хранение параметров KDF в БД реализовано.
- Автоматическое обновление хешей при успешном входе реализовано.
- Есть runbook на случай утечки.
Конфиденциальность и соответствие регуляциям
- Необходимо уведомлять пользователей и регуляторов в срок и форме, предусмотренных законом (например, GDPR для ЕС). Сообщения должны содержать информацию о типе утечки, объёме и рекомендованных действиях для пользователей.
- Обработка персональных данных и паролей требует минимизации хранения и документирования прав доступа.
Когда стоит перевести пользователей на сброс пароля
- Если хеши хранились с устаревшим алгоритмом (например, MD5 или SHA1).
- Если соль была скомпрометирована вместе с хешем и алгоритм устарел.
- Если произошёл массовый доступ к базе.
Дерево решений для подхода к паролям
flowchart TD
A[Нужны ли пароли в вашей системе?] -->|Нет| B[Использовать OAuth / SSO]
A -->|Да| C[Есть регуляторные ограничения?]
C -->|Да| D[Хранить локально, но с KDF и аудитом]
C -->|Нет| E[Рассмотреть OAuth, иначе KDF локально]
D --> F[Выбрать алгоритм: Argon2/scrypt/bcrypt/PBKDF2]
E --> F
F --> G[Реализовать соль, версионирование, runbook]
G --> H[Тесты, мониторинг, регулярные обновления]Короткая сводка и рекомендации
- Первый и лучший выбор — избегать хранения паролей вообще и доверять OAuth/SSO.
- Если хешируете — всегда использовать соль и специализированный KDF (Argon2/scrypt/bcrypt/PBKDF2).
- Длина пароля важнее набора специальных символов; поощряйте фразы.
- Защитите инфраструктуру: HTTPS, права доступа, шифрование резервных копий и мониторинг.
- Подготовьте runbook и процессы уведомления пользователей на случай утечки.
Важно
Эти меры не гарантируют абсолютную безопасность, но существенно снижают риск и последствия компрометации.
Глоссарий в одну строку
- Хеш: односторонняя трансформация данных.
- Соль: уникальная случайная добавка к паролю.
- KDF: функция для получения ключей из пароля, медленная и настраиваемая.
- OAuth: протокол делегированной авторизации.
Конец руководства
Похожие материалы
Как удалить контакт в LinkedIn — пошагово
Как проверить видеокарту в Windows 11
Как установить VPN в Ubuntu — руководство
Microsoft Power Automate: руководство по автоматизации
Как включить тёмную тему в Facebook на Android