Why do people think that this is bad way to hash passwords?

The wrong things on your method are:

  • You use way too few iterations (20 is too low, it should be 20000 or more): password processing is still too fast, an attacker with a basic PC will still be able to "try" dozens of millions of passwords per second.
  • There is no salt: an attacker may attack several passwords with very low per-password cost, e.g. with precomputed tables of hashed passwords (in particular rainbow tables).
  • You are in the process of inventing your own cryptography. There is nothing wrong with being inquisitive and trying to understand things, but since there is no sure test for knowing whether a given algorithm is secure or not, inventing your own cryptography is often a recipe for disaster. Don't do it.

What you should do is to use bcrypt; there is a PHP implementation in the Portable PHP password hashing framework.


Others have described the limitations of this hashing method; I'd like to point out a conceptual mistake in the question:

I don't think that attacker with my DB would be able to decrypt any password with lenght > 2

Attacker would have to decrypt this list of md5 hashes to be able to gain plain-password:

[list of intermediate results]

The mistake here is thinking that the complexity of the intermediate results provides any protection at all against a brute-force dictionary attack. I think the asker is thinking the attack must work backward, starting from the stored hash, and brute-force each intermediate result in turn.

This isn't true at all; reasonable dictionary attacks will start with possible passwords, and attack the whole 20-hash stack at once. Here's the algorithm sketch:

for each candidate password:
    hash 20 times
    compare with stored hash

Using this to check all possible 3-character passwords (assuming printable ASCII) would require only 20 * 95^3 = 17147500 hashes, which is basically trivial. Using SHA-512 instead of MD5, despite having much larger intermediate values, would be more secure only because each hash takes a little longer to compute.

tl;dr a complex hash function can't save you if the password itself doesn't have enough entropy.


20x MD5 is a fast hashing algorithm, meaning it can generate passwords at an astonishing rate.

Please stop using fast hashing algorithms to store passwords. Even with individual salts; if someone has direct (read: offline) access to your database they can be computed very easily.

This article explains why much better than I can:

http://codahale.com/how-to-safely-store-a-password/

The article heavily mentions BCrypt (with a link to a PHP library), but bear in mind there are other slow hashing algorithms that may suit you.