Соль в алгоритмах хеширования паролей представляет собой случайную последовательность байтов, которая добавляется к исходному паролю перед его хешированием. Основная задача соли — устранение предсказуемости результата хеш-функции при одинаковых входных данных и обеспечение уникальности итогового хеша даже для одинаковых паролей.
Энтропия соли определяет степень её случайности и непредсказуемости. Чем выше энтропия, тем сложнее восстановить исходные данные или использовать предрассчитанные таблицы хешей.
Энтропия в криптографическом контексте измеряется в битах и отражает количество возможных состояний, которые может принимать случайная величина.
Соль с энтропией 128 бит означает, что количество возможных вариантов равно:
2^128
Такое пространство делает перебор практически невозможным при современных вычислительных ресурсах.
Качество соли напрямую зависит от источника генерации:
Низкая энтропия:
Высокая энтропия:
В среде Node.js стандартом считается использование модуля crypto:
import crypto from 'crypto';
const salt = crypto.randomBytes(16);
16 байт дают 128 бит энтропии, что является промышленным стандартом для соли.
Алгоритмы хеширования паролей (включая реализации, подобные password-hash) используют соль для защиты от нескольких классов атак.
Радужные таблицы представляют собой предрасчитанные наборы соответствий «пароль → хеш». Без соли одинаковые пароли всегда дают одинаковый хеш, что делает такие таблицы эффективными.
Добавление уникальной соли к каждому паролю приводит к следующему:
hash = H(password + salt)
Даже при одинаковых паролях результат будет различным, что делает невозможным использование универсальных таблиц.
В системах без соли повторяющиеся пароли приводят к одинаковым хешам в базе данных. Это позволяет злоумышленнику:
Соль разрушает эту корреляцию, делая каждый хеш уникальным.
Длина соли напрямую влияет на количество возможных комбинаций.
| Длина соли | Энтропия | Уровень стойкости |
|---|---|---|
| 8 байт | 64 бит | недостаточный для современных систем |
| 12 байт | 96 бит | минимально допустимый |
| 16 байт | 128 бит | стандартный уровень |
| 32 байта | 256 бит | избыточный, но безопасный |
Увеличение длины соли не замедляет работу системы значимо, поскольку операция выполняется однократно при хешировании.
В JavaScript-библиотеках типа password-hash соль используется совместно с различными хеш-функциями:
Каждый из алгоритмов по-разному комбинирует соль и пароль, но общая модель остаётся одинаковой:
Пример структуры результата:
algorithm$salt$hash
или в бинарном виде:
{ salt: ..., hash: ... }
Стойкость системы хеширования паролей определяется совокупностью факторов:
Даже идеальная соль не защищает слабый пароль. Если пароль имеет низкую энтропию (например, словарные значения), атаки перебора остаются возможными.
Соль должна быть уникальной и непредсказуемой. При энтропии ниже 96 бит появляются теоретические возможности оптимизации атак.
Современные алгоритмы увеличивают стоимость вычисления хеша:
Высокая стоимость делает перебор менее эффективным даже при наличии GPU-ферм.
Соль не защищает напрямую от перебора, но делает невозможным массовое ускорение атак через предварительные вычисления.
В практических реализациях password-hash часто встречаются критические ошибки:
const salt = Math.random().toString();
Такой подход приводит к:
Использование одной соли для всех пользователей полностью нивелирует её защитную функцию.
Разделение соли и хеша в разных хранилищах увеличивает риск компрометации системы. Корректная практика — хранить их вместе.
Криптографическая стойкость системы password-hash можно приблизительно оценить как сумму факторов:
S = E_password + E_salt + C_algorithm
где:
При E_salt ≥ 128 бит вклад соли в возможность взлома становится практически незначимым, поскольку основным ограничением остаётся энтропия пароля и стоимость вычислений.
В современных криптографических практиках соль перестала быть опциональным элементом. Она рассматривается как обязательный компонент любой схемы хранения паролей.
В рамках password-hash подхода соль выполняет не только защитную, но и структурную роль: