| > Isn't the reason this is true that bcrypt just truncates the input at 72 characters? And if that's correct, aren't there basically a few options, any of which basically invalidate the argument? Let's run a scenario to show by bcrypt from strictly a CPU load perspective is better than sha256/512crypt. > 1. Enforce a password length limit. Fixes the unbounded growth of the shacrypt CPU time while simultaneously ensuring bcrypt is not ignoring input. Assume that I know how many authentications per second are happening on my busy authentication server, and I can reliably guarantee 0.25 seconds per request without creating an outage. On my hardware, that's a bcrypt cost of 12. If I pre-hash every password with SHA-256, then base64 encode the hash, and send that to bcrypt, I can guarantee every user any arbitrary length of password, and know that it will not take more than 0.25 seconds. For sha256crypt, a cost of 250,000 rounds is similar in performance for an 8-character password, executing in about 0.250158 seconds. However, and 36-character Diceware passphrase takes about 0.353884 seconds, and grows from there (70 characters at 0.503353 seconds, etc). Obviously, I can't allow everyone to have 36-character Diceware passphrases with a sha256crypt cost of 250,000 rounds. It would create load problems on my hardware. I have three options that I see ahead of me if I wanted to stick with sha256crypt: 1. I could decrease the sha256crypt rounds, so those who want longer passwords won't create a CPU outage due to load. 2. Enforce maximum password length limit of 35 characters, to prevent the execution time from taking too long. 3. Make some exceptions in the code, so those with 1-10 characters have a higher sha256crypt cost than those with 11-24, which is still higher than those with 25-36, etc. If I just stick bcrypt on the server with a cost of 12, I don't have handle these exceptions. > 2. Pre-hash the input to bcrypt by passing it through SHA512. Makes bcrypt now grow in the exact same way as shacrypt. No it doesn't. In the graphs on my post, the bcrypt timings are based on https://passlib.readthedocs.io/en/stable/lib/passlib.hash.bc.... bcrypt only grows when the cost is increased. Its execution times are in no way affected by password length. > 3. Don't enforce a password limit, but truncate the password. Fixes the CPU time. This is a bad design, and falls back to the security vulnerabilities of DES-Crypt and LM hashes. > Passing 4096 bytes to bcrypt is the same as passing 72 bytes to bcrypt because it ignores the last 4024 bytes right? Unless you bcrypt(base64(sha-256(password))), which is a common approach. |
If we acknowledge that pre-hashing is acceptable (and almost certainly more secure) for bcrypt, why can't we allow the same for shacrypt? If we do, all of the performance issues about shacrypt go away. You now have a fixed-length password.
shacrypt(sha-256(password))
bcrypt is always fast because it truncates to 72 characters. Because it truncates, you should pre-hash. shacrypt is slow for big inputs because it doesn't truncate. Because it is slow, you should pre-hash. If we accept both of these, there's really no difference in bcrypt and shacrypt is my point. I don't understand why you allow it as an option for bcrypt but not shacrypt.