В bcrypt.js ключевой параметр производительности — cost factor (rounds). Он определяет, сколько итераций хэш-функции будет выполнено при генерации хэша пароля. Каждый дополнительный шаг увеличивает время вычисления экспоненциально.
Формально зависимость времени можно выразить так:
T ^{cost}
где cost — это значение rounds (обычно от 8 до 15+), а
T — относительное время выполнения.
Важно учитывать, что bcrypt специально разработан как медленный алгоритм, чтобы усложнить brute-force атаки. Поэтому увеличение rounds всегда является компромиссом между безопасностью и производительностью.
Каждое увеличение cost на 1 удваивает вычислительную нагрузку. Это означает:
Такой рост делает подбор паролей вычислительно дорогим даже для современных GPU-ферм.
Для измерения производительности bcrypt.js используется простая схема бенчмарка:
import bcrypt from 'bcryptjs';
async function benchmark(cost) {
const password = 'secure_password_123';
const salt = bcrypt.genSaltSync(cost);
const start = process.hrtime.bigint();
bcrypt.hashSync(password, salt);
const end = process.hrtime.bigint();
return Number(end - start) / 1e6; // миллисекунды
}
(async () => {
for (let cost = 8; cost <= 14; cost++) {
const time = await benchmark(cost);
console.log(`cost ${cost}: ${time.toFixed(2)} ms`);
}
})();
Методика:
process.hrtime.bigint()Результаты зависят от железа, но характер роста стабилен:
| Cost | Время хэширования |
|---|---|
| 8 | ~2–5 ms |
| 9 | ~4–10 ms |
| 10 | ~8–20 ms |
| 11 | ~15–40 ms |
| 12 | ~30–80 ms |
| 13 | ~60–160 ms |
| 14 | ~120–320 ms |
При этом важно учитывать:
Рост времени можно представить как экспоненциальную функцию:
T(c) = T_0 ^{(c - c_0)}
где:
T(c) — время при cost = cT_0 — базовое время при минимальном costc_0 — базовый уровень (например, 8)Эта модель хорошо согласуется с реальными измерениями bcrypt.
Выбор rounds напрямую влияет на:
Чем выше cost, тем дороже атака перебором. При cost ≥ 12 brute-force становится практически нецелесообразным для большинства атакующих.
Каждая регистрация или смена пароля блокирует CPU на время хэширования.
При высокой нагрузке время хэширования становится узким местом.
На практике часто используют следующие диапазоны:
bcrypt.js предоставляет два подхода:
Разница особенно заметна при высоких cost:
Производительность bcrypt зависит от:
GPU ускорение в bcrypt.js не применяется, так как алгоритм намеренно защищён от массового параллелизма.
Бенчмарки bcrypt нельзя рассматривать как линейную метрику производительности. Они используются для:
Главный вывод из измерений:
увеличение cost всегда улучшает безопасность, но делает операции входа и регистрации всё более дорогими по CPU, причём рост стоимости носит экспоненциальный характер.