Библиотека bcrypt.js реализует алгоритм хеширования паролей bcrypt, адаптированный для JavaScript-окружения. Основная задача алгоритма — преобразование исходного пароля в необратимую строку фиксированного формата, устойчивую к атакам перебора и радужным таблицам. Ключевой особенностью bcrypt является наличие встроенной «стоимости вычислений» (cost factor), которая позволяет увеличивать сложность хеширования по мере роста вычислительных мощностей.
В контексте браузера bcrypt.js выполняет те же операции, что и серверные реализации: генерация соли, многократное применение ключевой функции EksBlowfish и формирование итогового хеша. Однако перенос этих операций на клиентскую сторону меняет модель угроз и архитектурные допущения.
Хеширование пароля до отправки на сервер предполагает, что пользовательский ввод преобразуется в bcrypt-хеш непосредственно в браузере, после чего на сервер передаётся уже не пароль, а его производная форма.
В таком подходе сервер может:
Ключевая мотивация подобной архитектуры — снижение риска перехвата пароля в открытом виде при передаче по сети и попытка уменьшить доверие к клиентскому каналу.
При корректной реализации TLS даже сам пароль не передаётся в открытом виде, однако клиентское хеширование добавляет дополнительный слой защиты. Сервер получает уже преобразованное значение, которое само по себе не является паролем пользователя.
Это снижает последствия возможной компрометации сетевого трафика в случае некорректной конфигурации TLS или его отсутствия.
Некоторые серверные системы логируют входящие запросы. При клиентском хешировании в таких логах не оказывается исходный пароль, а только его bcrypt-представление. Это уменьшает риск утечки секретов через инфраструктурные компоненты.
bcrypt является вычислительно дорогим алгоритмом. Перенос хеширования на клиентскую сторону уменьшает количество CPU-операций на сервере, что может быть значимо при массовой регистрации пользователей.
При клиентском хешировании сервер работает исключительно с уже готовыми bcrypt-значениями, что упрощает унификацию хранения и исключает необходимость повторного хеширования при входе или регистрации.
Основная проблема заключается в том, что bcrypt-хеш, вычисленный на клиенте, становится фактически новым паролем. Если злоумышленник перехватывает этот хеш, он может использовать его для аутентификации без необходимости восстановления исходного пароля.
Таким образом, вместо защиты пароля происходит его подмена другим секретом, который может быть повторно использован.
Если в приложении присутствует уязвимость XSS, злоумышленник получает доступ к клиентскому окружению до выполнения хеширования. В таком случае он может перехватить исходный пароль до преобразования или получить уже готовый bcrypt-хеш.
Клиентское хеширование не добавляет защиты от атак внутри доверенной сессии браузера.
bcrypt изначально проектировался как серверная функция хранения паролей. Его цель — замедлить офлайн-атаки после компрометации базы данных.
При переносе на клиентскую сторону теряется ключевой смысл: сервер перестаёт хранить результат, полученный из неизвестного ему секрета, и начинает принимать готовый хеш как входной секрет.
Если клиентский bcrypt-хеш используется напрямую для аутентификации, он превращается в постоянный токен доступа. Это означает:
Современные системы уже используют TLS, HSTS, защиту от MITM, secure cookies и серверное хеширование. Добавление bcrypt на клиенте часто не решает новую проблему, а лишь переносит вычислительную и архитектурную сложность в браузер.
bcrypt.js реализован полностью на JavaScript без нативных зависимостей. Это делает его совместимым с браузером, но накладывает ограничения:
При увеличении cost factor время вычисления может достигать сотен миллисекунд и более, что заметно влияет на UX при регистрации и входе.
bcrypt является алгоритмом, намеренно замедленным для защиты от перебора. В браузере это приводит к следующим эффектам:
Использование Web Workers позволяет частично вынести вычисления из основного потока, но не устраняет саму стоимость алгоритма.
Клиент выполняет предварительную обработку, сервер — финальную проверку и хранение. Такая схема редко оправдана, так как приводит к двойному хешированию и усложнению логики без существенного прироста безопасности.
Наиболее распространённая и устойчивая схема:
Эта модель сохраняет корректное разделение ответственности и соответствует изначальному назначению bcrypt.
Использование bcrypt-хеша как единственного секретного значения приводит к тому, что система фактически хранит «пароль-артефакт». Это упрощает реализацию, но снижает гибкость управления безопасностью и усложняет отзыв доступа.
Браузер не может считаться полностью доверенной средой. Любой JavaScript-код на странице может быть модифицирован через:
По этой причине выполнение криптографически значимых операций на клиенте всегда требует оценки угрозы перехвата на уровне исполнения, а не только канала передачи.
Эти факторы делают поведение алгоритма менее предсказуемым в клиентской среде.
bcrypt автоматически генерирует соль, что снижает риск повторного использования хеша. Однако при клиентском хешировании:
Даже при использовании клиентского хеширования остаются актуальными:
Без этих механизмов клиентское хеширование не даёт дополнительной защиты по сравнению с классической серверной моделью.