«Соль» всплывает, как только заходит речь о хешировании паролей. Добавление одного случайного значения перед хешированием кардинально меняет картину безопасности. Вот как это работает и ключевые моменты (без шагов атаки).
Почему соль делает пароли безопаснее
Без соли пользователи с одинаковым паролем получают одинаковый сохранённый хеш. Это даёт атакующему две возможности: найти пароль напрямую в предвычисленной таблице (радужной таблице) и использовать результат взлома одного аккаунта для всех, у кого тот же пароль.
Добавьте соль — и тот же "password123" хранится как нечто совершенно иное для каждого пользователя.
По той же причине соль должна генерироваться заново для каждого пользователя (в идеале для каждого пароля). Если у всех одна общая соль, у пользователей с одинаковым паролем снова совпадут сохранённые значения, и большая часть пользы теряется. Используйте трудно предсказуемый криптографический генератор случайных чисел и храните соль рядом с хешем (она не обязана быть секретной).
Соль защищает только от предвычисленных таблиц и массового взлома повторяющихся паролей. Замедлять перебор одного конкретного пароля — не её задача; этим занимается намеренно медленный хеш, такой как bcrypt/Argon2. Они закрывают разные угрозы, поэтому всегда используйте оба.
Длина соли и как её генерировать
Базовый уровень задают два документа:
- NIST SP 800-63B-4 (руководство США по аутентификации): соль должна быть не короче 32 бит и выбираться так, чтобы сохранённые соли редко совпадали. Для каждого пароля хранятся и соль, и хеш
- RFC 9106 (спецификация Argon2): для хеширования паролей рекомендуется 16 байт (128 бит), при нехватке места допустимо сократить до 64 бит
Три правила генерации:
- Используйте криптографический генератор случайных чисел. Используйте безопасную функцию случайных чисел вашего языка, а не предсказуемые вроде
Math.random()илиmt_rand()в PHP - Не используйте угадываемые значения: имя пользователя, адрес почты, ID пользователя или время регистрации не заменяют соль
- Генерируйте новую соль при смене пароля. Если оставить старую, между старым и новым хешем сохраняется связь
На практике стандартные реализации bcrypt, Argon2 и scrypt выполняют всё это автоматически. Если вы пишете код, который сам создаёт соли, считайте это поводом его пересмотреть.
Соль, перец и растяжение ключа
В хранении паролей участвуют три меры с похожими названиями. Они защищают от разного, поэтому ни одна не заменяет другую.
| Соль | Перец | Растяжение ключа (медленное хеширование) | |
|---|---|---|---|
| Что это | Случайное значение на каждого пользователя | Секретное значение, общее для всех пользователей | Намеренное удорожание вычисления хеша |
| Секретно? | Нет (хранится с хешем) | Да (хранится вне базы данных) | Параметры не обязаны быть секретными |
| Защищает от | Предвычисленных таблиц, массового взлома одинаковых паролей | Взлома, когда утекла только база данных | Перебора по каждому хешу |
| Реализация | Добавляется автоматически bcrypt/Argon2 | Добавляете сами при необходимости | Стоимость bcrypt, память и итерации Argon2 |
NIST SP 800-63B-4 рекомендует хранить «секретный ключ, известный только проверяющей стороне» (то, что обычно называют перцем), отдельно от хешей паролей, в идеале внутри специального оборудования, например HSM.
Реальный случай: хранение без соли в LinkedIn (2012)
В июне 2012 года сообщалось, что в интернете опубликовано около 6,5 млн хешей паролей, якобы принадлежащих пользователям LinkedIn. LinkedIn подтвердила, что часть из них соответствует аккаунтам LinkedIn, и аннулировала пароли затронутых участников.
В официальном блоге компания сообщила, что переходила от системы, которая только хешировала пароли, к системе, которая и хеширует, и солит их. Эксперты, которых тогда цитировала пресса, критиковали компанию за то, что пароли защищались только хешированием SHA-1.
Два урока:
- Хеши без соли позволяют массово восстанавливать распространённые пароли по предвычисленным таблицам
- Даже в середине миграции, если остались хеши в старом формате, последствия утечки определяются этим старым форматом
Как проверить свою среду
Посмотрите на форму сохранённых строк
В базе данных разработки, которой вы управляете, посмотрите на несколько значений паролей. Для bcrypt 22 символа после $2b$12$ — это соль. Для Argon2 за $argon2id$v=19$m=…,t=…,p=…$ следуют соль и хеш, разделённые $. Если значение не похоже ни на одну из этих форм и отдельного столбца с солью нет, пароли могут храниться без соли.
Создайте две тестовые учётные записи с одинаковым паролем
В среде разработки зарегистрируйте две тестовые учётные записи с одинаковым паролем и сравните сохранённые значения. Если они совпадают, соль не работает. Также убедитесь, что часть с солью меняется при смене пароля.
Поищите код, который собирает соль вручную
Поищите в коде слово salt и места, где функции случайных чисел или хеширования комбинируются вручную. Если найдёте предсказуемую функцию случайных чисел, повторное использование имени пользователя или ID либо фиксированную строку, замените это стандартной функцией для паролей из вашего языка или фреймворка.
Для миграции используйте практическое руководство
Как уйти от хранения без соли (например, перехешированием при входе) и рекомендуемые настройки для каждого алгоритма разобраны в статье как безопасно хранить пароли.
Распространённые заблуждения против правды
Заблуждение
- Соль должна храниться в секрете
- Одна общая соль для всех пользователей — это нормально
- Соль делает безопасными даже слабые пароли
Правда
- Соль может быть публичной (храните её с хешем)
- Разное случайное значение на каждого пользователя (в идеале на каждый пароль)
- Соль защищает от «предвычисления и взлома повторов»; перебор обрабатывается медленным хешем
Мнение этого сайта: сначала правильно настройте соль и медленное хеширование
Перец — дополнительная мера на случай, когда украдена только база данных. Она добавляет работу по управлению секретом в другом месте, а если этот секрет потерять, проверить чей-либо пароль станет невозможно.
Поэтому на практике первый приоритет — правильно использовать соль + медленный хеш через bcrypt/Argon2. О перце стоит задуматься, когда у вас уже есть налаженное управление ключами.
Источники (первичные)
- NIST, «SP 800-63B-4 Digital Identity Guidelines: Authentication and Authenticator Management» (август 2025) — pages.nist.gov (соль не менее 32 бит, хранение соли и хеша, отдельно хранимый секретный ключ)
- RFC 9106, «Argon2 Memory-Hard Function for Password Hashing and Proof-of-Work Applications» — rfc-editor.org (для хеширования паролей рекомендуется соль 16 байт)
- OWASP, «Password Storage Cheat Sheet» — cheatsheetseries.owasp.org (соль, перец; большинство библиотек обрабатывают соль автоматически)
- Формат строки PHC (формат строки хеша, используемый Argon2 и другими) — github.com/P-H-C
- TechCrunch, «LinkedIn Confirms Hack And Leak Of 'Some' User Passwords» (6 июня 2012) — techcrunch.com (около 6,5 млн, заявление компании о переходе к хешированию с солью)
- Computerworld, «LinkedIn provides breach update -- sort of» (8 июня 2012) — computerworld.com (критика хеширования только SHA-1, аннулирование паролей)
Читать дальше
- Глоссарий: что такое хеширование паролей (понимайте это вместе с солью)
- Обучение: как безопасно хранить пароли (хеширование + соль на практике)
- Основы: правильное хранение паролей