Гид по технологиям

bcrypt в Node.js: хеширование и соление паролей

5 min read Безопасность Обновлено 06 Dec 2025
bcrypt в Node.js: хеширование и соление паролей
bcrypt в Node.js: хеширование и соление паролей

Телефон поверх толстой книги, окружённые большой металлической цепью

Одним из лучших способов надёжно хранить пароли является их хеширование с добавлением соли. Процесс преобразует обычный пароль в уникальное значение, обратное восстановление которого затруднено. Библиотека bcrypt в Node.js позволяет выполнять эти операции просто и безопасно.

Что такое хеширование паролей?

Хеширование паролей — это применение хеш-функции к текстовому паролю для получения фиксированного уникального значения, называемого хешем. Хеш-функция детерминирована: один и тот же ввод даёт один и тот же результат. Примеры алгоритмов: bcrypt, scrypt, Argon2 и SHA-семейство (SHA не рекомендуется для паролей без соли и адаптивного фактора).

Ключевая проблема детерминированности — уязвимость к атаке по таблице предварительно вычисленных хешей (rainbow tables). Атакующий может заранее посчитать хеши для популярных паролей и быстро их сопоставить. Эту слабость устраняет добавление соли.

Что такое соль и зачем она нужна?

Соль — это случайная строка, добавляемая к паролю перед хешированием. Благодаря соли один и тот же пароль будет давать разные хеши при каждом создании учётной записи. Даже при утечке базы данных атакующему придётся тратить ресурсы на каждую запись отдельно.

Короткое определение: соль делает хеш уникальным для каждой записи и предотвращает массовое использование предвычисленных таблиц.

Как использовать bcrypt в Node.js

Ниже — пошаговая инструкция с примерами кода. Всё представлено на JavaScript для Node.js.

Шаг 1: установка bcrypt

Установите пакет через npm или yarn.

npm install bcrypt

или

yarn add bcrypt

Шаг 2: импорт библиотеки

В начале файла импортируйте bcrypt.

const bcrypt = require("bcrypt");

Шаг 3: генерация соли

Вызовите bcrypt.genSalt(), чтобы получить соль. Этот метод принимает целое число — фактор стоимости (cost factor), который определяет, сколько вычислительной работы требуется для хеширования. Чем выше фактор, тем медленнее работа и тем сложнее подобрать пароль перебором.

Обычно фактор стоимости выбирают в диапазоне 5–15; часто рекомендуют 10 как разумный баланс между безопасностью и производительностью.

Пример с колбэком:

bcrypt.genSalt(10, (err, salt) => {
  if (err) throw err;
  // используйте salt для хеширования
});

Шаг 4: хеширование пароля

Передавайте исходный пароль и соль в bcrypt.hash(). Можно сначала сгенерировать соль, а затем хешировать, либо воспользоваться упрощённой функцией, которая делает всё сразу.

Генерация соли и хеширование в колбэке:

bcrypt.genSalt(10, (err, salt) => {
  if (err) throw err;
  bcrypt.hash(plaintextPassword, salt, (err, hash) => {
    if (err) throw err;
    // Сохраните hash в базе данных
  });
});

Хеширование с авто-генерацией соли (в один вызов):

bcrypt.hash(plaintextPassword, 10, (err, hash) => {
  if (err) throw err;
  // Сохраните hash в базе данных
});

Шаг 5: сравнение паролей для аутентификации

При логине вы сравниваете введённый пользователем пароль и хеш из базы с помощью bcrypt.compare(). Функция возвращает true, если пароль соответствует хешу.

bcrypt.compare(plaintextPassword, hash, (err, result) => {
  if (err) throw err;
  if (result) {
    // Пароль верный — выполняем аутентификацию
  } else {
    // Неверный пароль
  }
});

Использование async/await

bcrypt поддерживает промисы, поэтому можно писать асинхронно через async/await.

async function hashPassword(plaintextPassword) {
  const hash = await bcrypt.hash(plaintextPassword, 10);
  // Сохраните hash в базе данных
  return hash;
}

async function comparePassword(plaintextPassword, hash) {
  const result = await bcrypt.compare(plaintextPassword, hash);
  return result; // true или false
}

Использование промисов then/catch

function hashPassword(plaintextPassword) {
  bcrypt.hash(plaintextPassword, 10)
    .then(hash => {
      // Сохраните hash в базе данных
    })
    .catch(err => {
      console.error(err);
    });
}

function comparePassword(plaintextPassword, hash) {
  return bcrypt.compare(plaintextPassword, hash)
    .then(result => result)
    .catch(err => {
      console.error(err);
      return false;
    });
}

Когда хеширование с солью может не сработать

Important: хеширование и соль — не панацея. Примеры ситуаций, когда этого недостаточно:

  • Слабые пароли пользователей (password123, qwerty) всё ещё уязвимы к словарным атакам, даже если хранятся хеши.
  • Повторное использование паролей между сервисами — утечка с одного сайта позволяет атаковать другой.
  • Утечка непротектированных резервных копий базы данных или ключей приложения (например, «pepper») снижает преимущества хеширования.
  • Неправильная конфигурация фактора стоимости (слишком низкий) делает перебор быстрым.

Альтернативные подходы

Если вы оцениваете риск и производительность, рассмотрите другие алгоритмы:

  • Argon2 — современный и рекомендуемый алгоритм для хеширования паролей (заявлен как победитель конкурса PHC).
  • scrypt — устойчив к специализированному аппаратному ускорению, хорош для высоких затрат памяти.
  • PBKDF2 — широко поддерживается и стандартизирован, но требует правильной настройки параметров.

Выбор зависит от требований к производительности, доступному объёму памяти и уровня угроз.

Мини-методология внедрения (шаги для команды)

  1. Выберите алгоритм и фактор стоимости (начните с 10 для bcrypt или рекомендаций по Argon2).
  2. Реализуйте хеширование при создании/смене пароля.
  3. При аутентификации используйте безопасное сравнение (bcrypt.compare).
  4. Внедрите проверку силы пароля и правила блокировки после попыток входа.
  5. План миграции: храните маркер алгоритма и параметров рядом с хешем, чтобы постепенно переходить на новый алгоритм.
  6. Не храните пароли в логах и не отправляйте их в сторонние сервисы.

Фактбокс

  • Рекомендуемый фактор стоимости bcrypt: обычно 5–15; часто используют 10.
  • Соль: генерируется автоматически bcrypt и обычно имеет достаточно длины (встроена в формат хеша).
  • Хеши — необратимы при правильной настройке, но их можно проверить только подбором.

Рекомендации по безопасности

  • Всегда проверяйте силу пароля (длина, набор символов, черный список общих паролей).
  • Введите ограничения по числу попыток входа и задержки (rate limiting, exponential backoff).
  • Храните в базе данных только хеши и служебные метаданные (алгоритм, фактор).
  • Рассмотрите использование «pepper» — глобальной секретной строки, хранящейся вне БД (например, в менеджере секретов). Это увеличит безопасность при утечке базы, но усложняет управление.
  • Шифруйте резервные копии базы данных и используйте контроль доступа по ролям.

Роли и чек-листы

Разработчик:

  • Реализовать хеширование при регистрации и смене пароля.
  • Использовать bcrypt.compare для проверки.
  • Не логировать пароли.

Оператор/DevOps:

  • Хранить секреты (pepper) в безопасном хранилище.
  • Настроить мониторинг попыток входа и алерты на аномалии.

Менеджер безопасности:

  • Утвердить минимальные требования к паролям и фактору стоимости.
  • Планировать регулярный аудит и тесты на проникновение.

Критерии приёмки

  • Новые пароли сохраняются в базе только в виде хешей.
  • Для каждой записи указан алгоритм/параметры хеширования.
  • Проходят тесты сравнения паролей (unit tests) и интеграционные проверки входа.
  • При попытке логина с неверным паролем счётчик попыток увеличивается и при достижении порога вводится задержка/блокировка.

Краткое резюме

  • bcrypt упрощает безопасное хеширование паролей в Node.js.
  • Соль делает хеши уникальными и защищает от предвычисленных таблиц.
  • Важно комбинировать хеширование с проверкой силы пароля, ограничением попыток и хранением секретов.

Сводка для быстрой ссылки:

  • Используйте bcrypt или современную альтернативу (Argon2) с адекватным фактором стоимости.
  • Не забывайте проверять сложность пароля и лимитировать попытки входа.
  • Планируйте миграцию алгоритмов и храните параметры вместе с хешем.
Поделиться: X/Twitter Facebook LinkedIn Telegram
Автор
Редакция

Похожие материалы

Как устроить идеальную вечеринку для просмотра ТВ
Развлечения

Как устроить идеальную вечеринку для просмотра ТВ

Как распаковать несколько RAR‑файлов сразу
Инструменты

Как распаковать несколько RAR‑файлов сразу

Приватный просмотр в Linux: как и зачем
Приватность

Приватный просмотр в Linux: как и зачем

Windows 11 не видит iPod — способы исправить
Руководство

Windows 11 не видит iPod — способы исправить

PS5: как настроить игровые пресеты
Консоли

PS5: как настроить игровые пресеты

Как переключить камеру в Omegle на iPhone и Android
Руководство

Как переключить камеру в Omegle на iPhone и Android