I want to insist that this is a very important part. If you are 99.9% of applications or websites out there, the only time you need to run that hash is at registration, login and password change. All of these case will be fine if it's a bit slow. Don't lowball it.
Also informationally I would like to add that as part of their "meant to be slow" job, algorithm like bcrypt are built in a way that makes it extremely hard if not impossible to run on cheap massively parallelized hardware (eg: CUDA on GPU).
After reading more it seems the only mitigation is Layers of Security.
It did not win, and I believe it is only CPU hard and not also memory hard unlike argon2. Nevertheless techniques to do this have been explored academically and might make it into future designs.
In case it isn't obvious, please continue to use argon2 (I'm just mentioning this as a point of interest).
For whatever reason this seems to be seldom discussed but the general idea is as follows in hand-wavey fashion:
Set up HSM with a non-exportable symmetric key, set key usages to "encrypt only" and as one step of the hashing scheme you use, encrypt your hash through the HSM. Protected HMAC key would work too.
The result is that an attacker who compromises your password db cannot perform offline attacks on your passwords anymore - they now need to do key extraction on your HSM or remain in your infrastructure and keep running guesses through the HSM where it is relatively easy to monitor what is going on and they can't do a bajillion operations per second anymore.
Wish everyone running large user dbs like yahoo or linkedin etc applied anchoring to their password hashing - it's a relatively simple measure for an org "at scale" to make hash dumps alone useless.
http://ithare.com/client-plus-server-password-hashing-as-a-p...
Requiring client-side JavaScript for your login system seems fraught. I would much rather have an approach that does server side hashing exclusively, but gates it behind some kind of DDoS protection or rate-limiting.
You can still flood the server, but you're flooding it with things that take microseconds to compute, instead of 50ms.
> NOTE: BLAKE3 is not a password hashing algorithm, because it's designed to be fast, whereas password hashing should not be fast. If you hash passwords to store the hashes or if you derive keys from passwords, we recommend Argon2.
As stated in the parent, integrity check hashing (should be fast) and password hashing (should be slow) are very different things and should not be mixed to use wrong implementations.
As bcrypt and argon2 both have specific prefixes, you can still keep bcrypt hashes and verifier can work on both (assuming it supports argon2) while using argon2 for newer entries stored in a database. (Preferably update the old bcrypt into argon2 on next login or something.)
In fact, an other risk of bcrypt is that any nul byte will truncate the key, so you probably want to hash the password with something else (SHA384 or SHA512/256 for instance) then base64/base85-encode it before passing it to bcrypt.
For most of the 2010s I've been under the impression that password hashing was a solved problem and that this is the solution.
And yet I still see comments online saying to hash passwords with a salt + 10,000 rounds of PBKDF2. Why bother when you can just b/scrypt it? Is there still some benefit of the former over the latter?
1) It's a NIST standard. This may be necessary in some environments, typically just to check a box. (Yeah, I know...)
2) It's necessary for SCRAM (RFCs 5802, 7677), which is a much better login method based on passwords. This is applicable if your system uses GSS-API or SASL (e.g. dovecot IMAP logins).
If neither applies, my advice is to migrate to Argon2.
In general, no. Most "slow" hashing schemes are designed to be memory-hard and highly serial (more threads = more contention, not throughput). Some of the earlier approaches just try to maximize computational requirements, but modern research acknowledges the march of computing power makes that an inherently poor choice for long term sensitive data. Argon2 is just one of the more advanced versions of a memory-hard scheme, building on prior research. I could try to give a poor explanation, but instead I'll link you the spec which is very readable: https://github.com/P-H-C/phc-winner-argon2/blob/master/argon...
As per DOS: rate limit per ip and account, and it's not an issue.
They have to and do use tricks, they aren't just slow. You could trivially make sha256 slow by just applying it a million times (that's not even parallelizable as well), but scrypt et al improve on that by making the algorithm also require a lot of RAM, use complex instructions (hard to recreate on a GPU or FPGA) and so on.
It's really hard to do very well, look at cryptocurrencies trying to be ASIC resistant: They want every normal person to be able to mine it, and don't want companies to be able to build a machine that can eclipse the mining power of everyone which means centralization.
It is a good DOS target, you should definitely rate limit logins to mitigate that. Other strategies are requiring captchas for login or letting the client execute the hash function and just doing a simple (fixed time) comparison on the server side.
And more succinctly:
crypto hash fn != authenticated hash fn (like HMAC constructions) != PBKDF
A practical password cracking rig can probably do upwards of 10^11 hashes per second. The same rig can only do 10^5 bcrypt hashes per second.
Generally you want slow, high cpu & memory hash functions for password hashing. This is the opposite of what md5/sha/blake aim for, as they want to be fast as possible. A fast hash allows the attacker to make many guesses very quickly (i think you can get something like 2 billion sha256 hashes a second with high end gpus). A slow hash makes it harder for the attacker to take lots of guesses (adding high mem usage helps protect against using alternate architectures like fpgas to speed things up).
Anyways, for passwords use something like argon2.
Blake2/3, SHA-2/3, and other cryptographic hash functions are meant to be fast, while also effectively guaranteeing no collisions or any way of reversing the hash (pre-image attack). This makes them ideal for stuff like checking file integrity, message authentication, inputs for cryptographic signatures and the like. But since they’re meant to be fast, they’re very poor choices for hashing low-entropy data such as passwords - attackers can test vast numbers of passwords (even if you salt!!) on GPU hardware.
For low-entropy data, you want a hash function that is slow and hard to parallelize. Use a specialized password hashing algorithm like bcrypt, scrypt or Argon2, and tune it so it’s slow enough without impacting overall usability (e.g. takes 50ms on your server). These algorithms are resistant to parallelization, so attackers will only be able to test a small number of passwords per second. This slows attackers down and can prevent them from recovering passwords that might be recoverable if stored using SHA-2, etc.