Adding to the answer by @adeneo,
The point of bcrypt, pbkdf2, scrypt and modern password hashing strategies is to be slow.
Yes, if you get the resulting hash from the database (SQLi) you can just try passwords and attempt to verify each one.
However, just try passwords is a bit of an understatement. Let's look at some math.
The default cost of password_hash()
with bcrypt takes approximately 0.1 seconds to hash a password. So that means it takes about 0.1 seconds to verify a password hash.
There are about 1,000,000 words in the english language. To try each one, you'd need to verify 1,000,000 times. At 0.1 seconds per, that's 100,000 seconds (~27 hours).
27 hours for 1,000,000 guesses for a single password hash that was leaked. Since each hash comes with a salt, an attacker would need to repeat these guesses for each leaked hash.
If your database had 1 million users, just to try the dictionary against the passwords would take 76,000 CPU-years (1 CPU for 76,000 years, 76,000 CPUs for 1 year, or any trade between).
To put that in perspective, md5()
on a 25 GPU cluster can do about 180,000,000,000 guesses per second. To check those million dictionary entries against the million hashes from the DB, it'd take about 5.5 seconds.
137 GPU-seconds vs 76,000 CPU-years. That is why bcrypt is used.