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

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
Автор
Редакция

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

Несколько аккаунтов Skype: Multi Skype Launcher
Программное обеспечение

Несколько аккаунтов Skype: Multi Skype Launcher

Журнал для работы: повысить продуктивность
Productivity

Журнал для работы: повысить продуктивность

Персональные звуки уведомлений на Android
Android.

Персональные звуки уведомлений на Android

Скачивание шоу Hulu для офлайн‑просмотра
Стриминг

Скачивание шоу Hulu для офлайн‑просмотра

Microsoft Start: персонализированная новостная лента
Новости

Microsoft Start: персонализированная новостная лента

Как изменить имя в Epic Games быстро
Гайды

Как изменить имя в Epic Games быстро