В конце 1990-х годов проблема безопасного хранения паролей уже была очевидной: традиционные криптографические хеш-функции, такие как MD5 и SHA-1, проектировались для скорости, а не для устойчивости к перебору. Быстрое вычисление, являвшееся преимуществом для проверки целостности данных, становилось уязвимостью в контексте защиты паролей.
На этом фоне особое внимание привлек алгоритм шифрования Blowfish, разработанный Брюсом Шнайером в 1993 году. Blowfish представлял собой симметричный блочный шифр с переменной длиной ключа и сложной процедурой инициализации ключевого расписания. Ключевая особенность — значительное время, требуемое для генерации внутреннего состояния (key setup), что делало его интересным кандидатом для задач, где важна вычислительная «дороговизна».
В 1999 году Нильс Провос и Дэвид Мазьерес предложили алгоритм bcrypt, основанный на модифицированной версии Blowfish — Eksblowfish (expensive key schedule Blowfish). Основная идея заключалась в намеренном усложнении процесса инициализации ключа.
В классическом Blowfish ключ используется для генерации P-массивов и S-блоков. В Eksblowfish этот процесс повторяется многократно, причём в качестве входных данных используются:
Таким образом, вычисление хеша становится управляемо медленным процессом.
bcrypt был представлен как часть системы OpenBSD для безопасного хранения паролей. Его ключевые характеристики:
Структура bcrypt-хеша включает:
$2a$,
$2b$)Пример:
$2b$10$eImiTXuWVxfM37uY4JANjQ==Xq7vV9kK8P5s6z3v9w0qZcY1FZC1K
Со временем в bcrypt были обнаружены и устранены различные проблемы, что привело к появлению нескольких версий:
Эти различия важны при реализации, так как несовместимость форматов может привести к невозможности проверки пароля.
Несмотря на широкое распространение, bcrypt имеет ряд ограничений:
Тем не менее, благодаря своей адаптивности и проверенной временем архитектуре, bcrypt остаётся актуальным выбором для многих систем.
С развитием Node.js и браузерных приложений возникла потребность в реализации bcrypt на JavaScript. Так появилась библиотека bcrypt.js — чистая реализация алгоритма без использования нативных модулей.
Особенности bcrypt.js:
Однако из-за отсутствия нативной оптимизации bcrypt.js работает
медленнее, чем реализации на C/C++ (например, bcrypt для
Node.js). Это может быть как недостатком, так и преимуществом — в
контексте клиентских приложений дополнительная задержка может повысить
безопасность.
bcrypt остаётся одним из наиболее распространённых алгоритмов хеширования паролей, наряду с PBKDF2, scrypt и Argon2. Его простота, адаптивность и широкая поддержка делают его удобным выбором для большинства задач.
В контексте JavaScript bcrypt.js играет важную роль, обеспечивая переносимость и доступность криптографических механизмов в средах, где использование нативных модулей ограничено.
Развитие вычислительных мощностей и появление специализированного оборудования продолжают оказывать давление на алгоритмы хеширования, однако архитектурные решения, заложенные в bcrypt ещё в конце XX века, по-прежнему обеспечивают приемлемый уровень защиты при корректной настройке параметров.