Hi
On 2026-09-30 15:00, Andrey Andreev wrote:
The limit is 72 *bytes*, not 72 *characters*. This is a meaningful
difference: It means that users might be presented an error for
non-ASCII passwords.
That's a good argument *against* the current silent truncation
behavior,
because:
- It also means effective length can be at least halved, depending on
the
character set in use.
- Some character sets (most prominently UTF-16) specifically use NUL
bytes
inside character codes.
Not accounting for these issues violates modern security standards. I
could
list multiple, but in all honestly they're universal consensus on
what's
already established by NIST, so see that:
https://nvlpubs.nist.gov/nistpubs/SpecialPublications/NIST.SP.800-63B-4.pdf#subsubsection.3.1.1
You are correct in that the NIST standard specifies that:
9. Verifiers SHALL request the password to be provided in full (not a
subset of it) and SHALL verify the entire submitted password (e.g., not
truncate it)
However: The NIST standard applies to the “Verifier” (i.e. the
application), not to the primitive. While `password_hash()` is certainly
intended to be usable as-is, an application requiring strict compliance
with all SHALLs and SHOULDs of the NIST standard already needs to
perform some steps that cannot be solved by `password_hash()`, such as
verifying that known-insecure passwords cannot be used. And when trying
for pedantic compliance with NIST you cannot use BCrypt at all, since
BCrypt technically is not in the list of NIST-approved hashing
functions. For that you need an approved hash function, and my latest
knowledge is that neither BCrypt nor Argon2’s BLAKE2b primitive are
acceptable. In practice this means using `hash_pbkdf2()`.
If we ignore all that, implementing the RFC would mean that BCrypt
hashing with PHP would start to deviate from a combination of two
different requirements:
2. Verifiers and CSPs SHOULD permit a maximum password length of at
least 64 characters.
and
4. Verifiers and CSPs SHOULD accept Unicode [ISO/ISC 10646] characters
in passwords. Each Unicode code point SHALL be counted as a single
character when evaluating password length.
The RFC would thus trade a SHALL violation for a SHOULD deviation that
affects exactly the users using non-ASCII character sets.
And while the effective length is reduced for e.g. CJK characters, they
are also much more information dense than ASCII characters. An English
word taking up 5-7 bytes can often be represented as a single 3-byte CJK
character. Of course the RFC also does nothing about this: Instead of
reducing the effective length, inputs exceeding “the effective length”
are rejected, forcing the user to pick a shorter password. The
achievable security ceiling is the same - and high enough.
The NUL byte point is moot, because NUL bytes are already rejected
during hashing. For that I agree with the ValueError / check, since the
truncation on NUL is much more catastrophic - and because actually
including a NUL in a legit user-provided password is much more
complicated than exceeding a 72 byte limit. In practice the Internet has
also converged on “just using UTF-8”.
It is inappropriate for us to make such a decision for end users.
Doubly so
when the user would be completely unaware of it, which is what happens
when
you have silent truncation.
I've personally witnessed many lack-of-MFA "mitigation" strategies that
rely on absurdly-long passwords, and the people involved in those
decisions
didn't even include developers. GRC types and over-confident IT admins
trying to reason about how to use off-the-shelf software. To account
for
bcrypt's inherent limitation in this context would require people with
very
specialized skills and superhuman foresight.
I did the math in a sibling email: Truncating absurdly-long passwords
still results in “you ain't gonna need it” amounts of entropy.
The RFC is rather roughly-argumented as is (I'd be happy to help Sjoerd
with that) and there's plenty of room to debate on BC break grounds,
but
the problem it tries to address is spot on.
I don't necessarily disagree with the BCrypt truncation being a problem,
but in this case the cure is worse than the disease.
Best regards
Tim Düsterhus