Алгоритм bcrypt был разработан в эпоху, когда основным ориентиром были криптографические библиотеки на C и системное хранение паролей в Unix. Одной из ключевых технических особенностей реализации стало жесткое ограничение на размер входных данных: все символы после первых 72 байт игнорируются.
В bcrypt.js, как JavaScript-портировании оригинального
алгоритма, это ограничение сохранено полностью, поскольку оно заложено
не на уровне библиотеки, а на уровне самой криптографической схемы.
Важно понимать:
bcrypt не работает с символами, он работает с байтами
Это означает, что строка в JavaScript сначала кодируется (обычно в UTF-8), и уже затем ограничивается первыми 72 байтами.
Ограничение связано с исторической реализацией bcrypt на базе алгоритма Blowfish. Внутренний ключевой материал имеет фиксированный размер, и при расширении ключа используется только ограниченный буфер.
Фактически:
Это не искусственное ограничение JavaScript-реализации, а фундаментальная часть криптографической конструкции.
При обработке пароля происходит следующая последовательность:
Пример:
Пароль: "password123" + очень длинная строка
Если длинная строка выходит за пределы 72 байт, она никак не влияет на результат хэширования.
Самое важное последствие ограничения — потеря энтропии при длинных паролях.
Рассмотрим два пароля:
A: "correcthorsebatterystaple"
B: "correcthorsebatterystaple + 1000 символов"
Если первые 72 байта совпадают, то:
Это создаёт классическую проблему:
длинный пароль не всегда означает более безопасный пароль
В JavaScript строки используют UTF-16, но bcrypt.js при обработке переводит их в UTF-8. Это приводит к дополнительным нюансам:
Пример:
"а" (кириллица) → 2 байта
"?" → 4 байта
Следствие:
72 символа ≠ 72 байта
Реальная длина строки в символах может быть значительно меньше допустимого лимита в байтах.
Если пользователь вводит пароль длиной более 72 байт:
Злоумышленник может:
Это не делает bcrypt “сломленным”, но снижает эффективность длинных паролей как средства защиты.
Системы часто принимают:
Но в контексте bcrypt:
Некоторые системы разрешают пароли:
Но при использовании bcrypt.js:
всё после 72 байт просто исчезает из криптографического расчёта
Иногда пытаются обойти ограничение:
const hashed = bcrypt.hashSync(sha256(password), salt);
Это приводит к:
Если система не ограничивает длину входа:
Пароль A: "securepassword123AAAAAAAAAAAAAAAAAAAAAAAAAAAA"
Пароль B: "securepassword123BBBBBBBBBBBBBBBBBBBBBBBBBBBB"
Если различия начинаются после 72 байт:
При переходе с:
на bcrypt.js может возникнуть неожиданное поведение:
Практическая мера:
Перед хэшированием:
Важно учитывать:
В отличие от bcrypt:
bcrypt.js сохраняет ограничение:
72 байта — это фундаментальная константа алгоритма
Ключевые эффекты: