Соль — это случайная строка данных, добавляемая к паролю перед его хешированием. Она не является секретной и хранится вместе с хешем. Основная задача соли — сделать каждый результат хеширования уникальным, даже если исходные пароли совпадают.
Формально процесс выглядит так:
hash = H(password + salt)
где H — криптографическая хеш-функция.
В библиотеке bcrypt.js соль является встроенной частью
алгоритма и используется автоматически, что избавляет от необходимости
реализовывать её вручную.
Без использования соли один и тот же пароль всегда даёт одинаковый хеш. Это приводит к ряду критических уязвимостей:
Соль устраняет эти проблемы. Даже если два пользователя выбрали
пароль 123456, их хеши будут различаться из-за разных
значений соли.
Алгоритм bcrypt изначально спроектирован с поддержкой соли. В
bcrypt.js при вызове функции хеширования:
const bcrypt = require('bcryptjs');
const hash = bcrypt.hashSync('password123', 10);
происходит следующее:
Итоговый хеш содержит:
Пример:
$2a$10$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36L7eFhK2X9z8cJ9b0q9K9a
Разбор:
$2a$ — версия bcrypt10 — cost factor (сложность)EixZaYVK1fsbw1ZfbX3OXe — сольСоль создаётся с помощью криптографически стойкого генератора
случайных чисел. В bcrypt.js можно явно управлять этим
процессом:
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync('password123', salt);
Параметр 10 определяет сложность (количество раундов), а
не длину соли.
Важно:
Rainbow tables — это заранее вычисленные таблицы соответствий между паролями и их хешами.
Без соли:
password → 5f4dcc3b5aa765d61d8327deb882cf99
С солью:
password + salt1 → hash1
password + salt2 → hash2
Атакующему пришлось бы создавать отдельную таблицу для каждой возможной соли, что делает атаку практически невозможной.
При проверке пароля соль не передаётся отдельно. Она уже встроена в хеш:
const isMatch = bcrypt.compareSync('password123', hash);
Процесс:
Это означает:
1. Повторное использование соли Использование одной и той же соли для всех пользователей сводит защиту к минимуму.
2. Ручная реализация соли Попытки самостоятельно добавлять соль поверх bcrypt избыточны и могут привести к ошибкам.
3. Хранение соли отдельно В bcrypt соль уже включена в итоговую строку. Дополнительное хранение усложняет систему без пользы.
Соль кардинально меняет модель угроз:
| Без соли | С солью |
|---|---|
| Одинаковые пароли → одинаковые хеши | Каждый хеш уникален |
| Уязвимость к rainbow tables | Защита от предвычисленных атак |
| Быстрое массовое взлом | Требуется индивидуальная атака |
| Утечка базы = мгновенный риск | Утечка требует значительных вычислений |
Соль и cost factor работают совместно:
В bcrypt:
bcrypt.hashSync(password, 12);
где 12 означает 2¹² итераций.
Даже если злоумышленник знает соль:
Соль превращает хеширование из простой функции в устойчивый к атакам механизм хранения паролей. Без неё даже сильный алгоритм может оказаться уязвимым.
В контексте bcrypt.js соль:
Это позволяет сосредоточиться на логике приложения, не реализуя криптографию вручную.