Bcrypt Password Hashing Silently Ignores Characters Beyond 72 Bytes, Breaking Verification Expectations

The bcrypt algorithm, widely used for password hashing in PHP and Python applications, processes only the first 72 bytes of any input password. Additional characters are ignored without error or warning during both hashing with password_hash and verification with password_verify. This behavior stems from the fixed 72-byte P-table size in the underlying Blowfish cipher as defined in the 1999 specification. Long passphrases, especially those using multibyte UTF-8 characters like Cyrillic or emojis, can result in completely different strings producing identical hashes. The limitation creates risks during password manager usage, system migrations, and scenarios involving shared prefixes. Modern libraries such as Python's bcrypt 4.x now explicitly reject passwords exceeding 72 bytes, while older implementations continue silent truncation. Recommended fixes include enforcing byte-length validation or pre-hashing with SHA-256 before bcrypt.

HabrTranslated from Russian

Read at source

The bcrypt password hashing algorithm silently truncates inputs after the first 72 bytes, causing any characters beyond that limit to be ignored during both hashing and verification. This behavior has existed since the algorithm's introduction in 1999 and remains unchanged to preserve hash compatibility.

Developers discovered the issue when importing accounts from legacy systems. Passwords longer than 72 bytes verified successfully even when they differed in the ignored tail, leading to unexpected authentication results. Tests in PHP using PASSWORD_BCRYPT confirmed that a 72-character string and a 100-character string of the same prefix produce matching verification outcomes.

The root cause lies in Blowfish's P-table, which holds exactly 18 subkeys of 4 bytes each. The original specification fixed this 72-byte boundary, and any excess data is never fed into the key expansion function. Multibyte characters exacerbate the problem: 36 Cyrillic characters reach the limit, while 37 or more are truncated.

Practical risks appear in password managers that store full-length strings, during database migrations between libraries with differing truncation rules, and in corporate environments using long static prefixes. Python's bcrypt package version 4.x now raises an explicit error for inputs over 72 bytes, forcing developers to handle truncation manually or upgrade validation logic.

Mitigations include adding consistent 72-byte length checks on registration and login forms, pre-hashing passwords with SHA-256 encoded in base64 before passing to bcrypt, or migrating to algorithms without length limits such as Argon2id or scrypt. Systems should also audit all code paths that call the hashing function to ensure uniform enforcement.

Meridian digestThe week's most consequential security stories, distilled into one briefing.See the digest

More in Vulnerabilities & Exploits

CISA Adds Cisco Secure Firewall and GitLab Flaws to Known Exploited Vulnerabilities Catalog
Telegram for Android Patches Voice Call Vulnerability Enabling Code Execution
Yandex Patches Millions of Stations After eMudhra Certificate Keys Compromised