bcrypt.js — это JavaScript-реализация алгоритма хеширования паролей bcrypt, разработанного для безопасного хранения секретных данных. Основная идея алгоритма заключается в том, чтобы преобразовать исходный пароль в необратимый хеш с использованием вычислительно затратной функции.
Ключевая особенность bcrypt — адаптивная сложность. Это означает, что со временем можно увеличивать стоимость вычислений (work factor), делая подбор паролей всё более дорогим по ресурсам.
В библиотеке bcrypt.js существуют два основных подхода:
Синхронный вариант реализуется через метод
bcrypt.hashSync, который выполняет хеширование немедленно,
блокируя поток выполнения JavaScript до завершения операции.
Базовая форма вызова:
bcrypt.hashSync(data, saltOrRounds)
data
stringsaltOrRounds
Тип: string | number
Возможные значения:
При вызове bcrypt.hashSync происходит несколько
этапов:
Вся операция выполняется в одном потоке, без передачи управления event loop до завершения вычислений.
const bcrypt = require('bcryptjs');
const password = 'mySuperPassword123';
const hash = bcrypt.hashSync(password, 10);
console.log(hash);
В этом примере:
10 означает количество раундов (cost factor)Число раундов определяет сложность вычислений.
bcrypt.hashSync(password, 12);
Каждое увеличение на 1 удваивает вычислительную сложность.
bcrypt позволяет передать готовую соль:
const salt = bcrypt.genSaltSync(10);
const hash = bcrypt.hashSync('password', salt);
Результат bcrypt.hashSync выглядит как строка:
$2a$10$EixZaYVK1fsbw1ZfbX3OXePaWxn96p36b8Zc1v2h4gkq8Z8n4l2mW
Разбор структуры:
$2a$ — версия алгоритма10 — cost factorСинхронное хеширование применяется в случаях, когда:
Node.js выполняет JavaScript в одном потоке. При вызове
hashSync:
app.post('/register', (req, res) => {
const hash = bcrypt.hashSync(req.body.password, 12);
// сервер "заморожен" во время вычисления
res.send(hash);
});
При множественных запросах это приводит к деградации производительности.
Синхронный метод:
const hash = bcrypt.hashSync(password, 10);
Асинхронный метод:
bcrypt.hash(password, 10, (err, hash) => {
console.log(hash);
});
Разница:
| Параметр | hashSync | hash (async) |
|---|---|---|
| Блокировка потока | да | нет |
| Производительность | ниже | выше |
| Удобство | выше | ниже |
bcrypt.js использует реализацию алгоритма EksBlowfish, который включает:
Синхронная версия оборачивает этот процесс в блокирующий вызов.
const users = ['admin', 'test', 'demo'];
const result = users.map(u => ({
username: u,
passwordHash: bcrypt.hashSync('defaultPass123', 10)
}));
for (let user of users) {
user.password = bcrypt.hashSync(user.password, 12);
}
bcrypt.hashSync(password, 20);
Это может привести к:
app.post('/login', (req, res) => {
const hash = bcrypt.hashSync(req.body.password, 12);
});
Ошибка заключается в блокировке каждого запроса.
bcrypt не предназначен для повторного хеширования своей же строки.
hashSync в API-серверахКаждый вызов:
При масштабировании системы это становится критическим ограничением.
Node.js не использует многопоточность для JavaScript-кода, поэтому:
При использовании bcrypt.hashSync важно учитывать:
| rounds | приблизительное время |
|---|---|
| 8 | быстро |
| 10 | умеренно |
| 12 | заметная задержка |
| 14 | высокая нагрузка |
Каждый шаг увеличивает время экспоненциально.
Если передано число:
bcrypt.hashSync(password, 10);
выполняется:
Даже при одинаковом пароле:
bcrypt.hashSync('123456', 10);
bcrypt.hashSync('123456', 10);
результаты будут различаться из-за случайной соли.
Синхронный метод часто применяется в:
Причина — простота и отсутствие асинхронной логики.
bcrypt.hashSync обеспечивает:
Безопасность определяется не методом (sync/async), а параметрами salt и rounds.