On Key-Stretching, Denial-of-Service and Future-Proofing
I had a really interesting conversation with a participant at my recent training at OWASP Melbourne’s always amazing event, AppSecDay Melbourne. We ran 3 Trainings at the event including our AppSec Essentials Training, DevSecOps MasterClass and our Containers and Kubernetes Security Training.
In the AppSec class, I spoke about Key-Stretching. I detailed specific reasons for why we should use Key-Stretching Algos like BCrypt/PBKDF2/Argon2 instead of plain ol’ hashing functions (even with salts). Hashes are inherently fast to compute, hence faster to crack. This opposed to Key-Stretching algos that use encryption OR Authentication Codes with rounds/work-factor to slow down the hashing process by several orders of magnitude.
One of the participants had an interesting question
What if an attacker (or group of attackers) used really long passwords that passed through a Key-Stretching algo (like BCrypt) leading to a Denial of Service state?
This is actually a very valid point. If an attacker decides to use a 100 character password, then the options that currently exist for a system that hasn’t planned for it:
- Restrict Password length => BAD!
- Truncate password to X characters => Also BAD! (See this)
- Not deal with that possibility => I’m sure this is the default thought-process for most
In fact, when I looked at Python’s BCrypt Library, I saw that it only allows you to handle a 72 character passwordand suggests a workaround instead.
I read about Dropbox’s implementation of Password Hashing, which deals with this situation quite comprehensively from a perspective of:
- Password Hashing without Length compromise
- Future Proofing
Dropbox’s approach is as follows:
- User’s Password is hashed as a SHA-512 Hash (producing a fixed-length hash regardless of length)
- SHA-512 hash is Key-stretched as a BCrypt Hash
- BCrypt hash is encrypted with AES-256 encryption protected with a single symmetric key across the entire population of hashes.
This, in their opinion assures future-proofing of their password protection system against a variety of attacks and engenders Defense-in-depth. And for a service at their scale, I can imagine that these are extremely important considerations. I consider this implementation more than resilient for the following reasons:
- They aren’t restricting password length for their users. The SHA512 hash ensures that
- They’re still protecting it with Key-Stretching with BCrypt. They are considering Argon2 moving forward per this article (from 3 years ago)
- Additionally, they are encrypting the password with AES-256 (strong cipher) as an additional layer of defense.
I’d probably do away with the AES encryption. But I am not Dropbox, so their threat model is not mine. But its certainly an interesting implementation
Bottom line: If you are using Key-Stretching algos for password protection, you should consider the DoS and size management problems that can be easily mitigated with standard hashing algos like SHA256/512
Check out Abhay and we45's upcoming public trainings and talks here