> It's common in practice even if it shouldn't be.
It should be though, the backend should reject overlong passwords, and the frontend should have such limits as well.
Though by "overlong" I mean kbyte range, not 32 character. The point of the limitation is to avoid randos feeding megabytes of data into your KDF and DOSing your server.
> Also many bcrypt implementations truncate input longer than 72 characters.
The alternative would be to error as bcrypt works on 18 words (of 32 bits). You need special handling (pre-hashing with a non-broken cryptographic hash function) to fix this issue.
Also it's 72 bytes not characters. And your pre-hash needs to generate some sort of textual representation (hex, base64, base85, …), as bcrypt will also truncate at the first NUL byte.
> The point of the limitation is to avoid randos feeding megabytes of data into your KDF and DOSing your server.
You shouldn't be using a KDF that takes significantly longer when the password gets bigger. If you make that mistake, even a kilobyte is going to be annoyingly slow. If you don't make that mistake, then even MAX_POST_SIZE passwords won't DOS you.
> You shouldn't be using a KDF that takes significantly longer when the password gets bigger.
Your KDF necessarily takes longer when the password gets longer as it's a hash function and thus O(n).
For typical password sizes (typically under 64 bytes), you're below the hash's blocksize so the effect is nil and you can treat it as a constant but it will start coming into play as the size of the key and thus the number of blocks to feed into the hash increases.
If you're really paranoid about cryptography then reject it. If you're slightly less paranoid then pass it through SHA512 before bcrypting it. Never silently truncate a password.
A year after you leave the job, your team is told to build a new auth backend against the database, using a different bcrypt implementation. They just know to use bcrypt, but not about your truncation hack. The deployment is a success.
Two weeks later, an angry user (the only one with a 100-digit password) complains that they can't log in anymore. The guy is the company's best-paying customer; the boss is furious. The whole team goes on a wild goose chase for two days and nights just to find out what happened, as clearly there's nothing wrong with their code.
A few years later, a former colleague shares the episode on HN. As you read the comments, it dawns on you that the idiot antagonist of the story is you. In this moment, you are enlightened.
The point of the upstream post was that bcrypt implementations often already truncate your passwords to 72 characters.
If you switch to a different bcrypt implementation that does/does not truncate at 72 characters, the server-side truncation keeps all those 73 character passwords working.
If the server-side truncation were not in place, you'd get angry users.
Suppose a user whose first name is Jonathan and whose wife's name is Katherine uses the password "JonathanAndKatherineLU8zWNmkimQanaSdPdqatWJEWR8goyyhdtQeqZOp2+0" and you truncate it to 20 characters.
So potentially even worse. Somebody decides they don't like variable-width encodings and uses UTF-32 and now 72 bytes doesn't even get you 20 code points, only 18.
But it's the same principle no matter where you cut. User thinks they can use an arbitrarily long password, puts a long but low entropy or easily guessable string at the front and makes up for it by having some good entropy at the end, and then you chop off the end.
Because you're misleading the user. Loudly complaining about invalid input is okay, but accepting and silently changing it in a way that affects it properties is not.
If your password is too long to fit in a hash scheme, then it's probably secure to just truncate and match. Unless the user has little entropy in the first part of their password, which i can't see happening.
Also many bcrypt implementations truncate input longer than 72 characters.