Проверка пароля в bcrypt.js основана на сравнении введённого пользователем значения с ранее сохранённым хэшем. Ключевой момент заключается в том, что исходный пароль никогда не восстанавливается из хэша — вместо этого вводимый пароль повторно проходит через тот же алгоритм хэширования и сравнивается результат.
Функция bcrypt.compare реализует этот процесс
асинхронно, что особенно важно для серверных приложений на Node.js, где
блокировка event loop приводит к деградации производительности.
Основной вариант использования:
bcrypt.compare(data, encrypted, callback)
Где:
data — пароль в открытом виде (строка, введённая
пользователем)encrypted — сохранённый bcrypt-хэш из базы данныхcallback — функция обратного вызова
(err, result)Возвращаемое значение при отсутствии callback —
Promise<boolean>.
Асинхронная версия bcrypt.compare использует
неблокирующие операции, выполняемые в отдельном потоке (thread pool).
Это критично, так как сам процесс проверки включает вычислительно
тяжёлую операцию повторного хэширования с учётом salt и cost factor.
bcrypt.compare(password, hash, (err, result) => {
if (err) {
console.error('Ошибка при проверке пароля:', err);
return;
}
if (result) {
console.log('Пароль корректный');
} else {
console.log('Пароль неверный');
}
});
bcrypt.compare(password, hash)
.then(result => {
if (result) {
console.log('Доступ разрешён');
} else {
console.log('Неверный пароль');
}
})
.catch(err => {
console.error('Ошибка проверки:', err);
});
async function checkPassword(password, hash) {
try {
const match = await bcrypt.compare(password, hash);
if (match) {
console.log('Авторизация успешна');
} else {
console.log('Неверный пароль');
}
} catch (err) {
console.error('Ошибка при сравнении:', err);
}
}
Алгоритм проверки включает несколько этапов:
Важно, что сравнение реализовано через безопасную функцию, предотвращающую утечки через timing attack.
Обычное строковое сравнение может быть уязвимо к анализу времени выполнения. bcrypt использует константное время сравнения, что исключает возможность определения совпадения по скорости ответа системы.
Это означает, что:
Асинхронная версия bcrypt.compare поддерживает обе
модели.
Асинхронная проверка не блокирует основной поток, однако сама операция остаётся ресурсоёмкой. Влияние определяется параметром cost factor, заданным при генерации хэша.
Чем выше cost factor:
При высокой нагрузке типичным решением является ограничение количества одновременных проверок и использование очередей задач.
bcrypt.compare(123456, hash)
Пароль должен быть строкой. Передача чисел или null может приводить к некорректным результатам.
bcrypt.compare(password, 'plain-text')
Второй аргумент должен быть валидным bcrypt-хэшем. В противном случае результат всегда будет false или возникнет ошибка.
bcrypt.compare(password, hash, (err, result) => {
if (result) {
// ошибка не обработана
}
});
Ошибки криптографического уровня (повреждённый хэш, некорректный формат) должны обрабатываться отдельно от результата сравнения.
При использовании bcrypt.compare в системах логина важно
учитывать:
Пример типового поведения:
const user = await db.findUser(username);
if (!user) {
return false;
}
const isValid = await bcrypt.compare(password, user.passwordHash);
return isValid;
Хэш bcrypt обычно хранится в поле фиксированной длины (60 символов). При извлечении из базы важно:
Существует bcrypt.compareSync, однако её использование в
серверной среде приводит к блокировке event loop.
Асинхронная версия предпочтительна, так как:
При большом количестве одновременных вызовов
bcrypt.compare:
Оптимизация обычно включает:
bcrypt.combine:
Асинхронная проверка сохраняет все эти свойства, так как использует тот же алгоритм, что и генерация хэша.