Would something like the following improve security (against rainbow attacks, not brute force)? Assume that $P$ is a user-chosen password, and the objective is to obtain a hash $H$ for password checking.

  • Let $S$ be a random salt.
  • Let $A_1 = MD5(P || S)$
  • Let $A_2 = MD5(A_1 || P) || A_1$
  • Let $H = MD5(A_2)$.

The idea is to increase the ciphertext length and the number of MD5 iterations by "salting" the hash with another hash of the password. Does that really help?

  • $\begingroup$ Please don't roll your own password hashing protocol. A single round of MD5 with any salt is not good enough. Use bcrypt, scrypt, or PBKDF2. $\endgroup$ Commented Aug 5, 2013 at 17:18
  • $\begingroup$ There are some things wrong with your scheme: inventing an own scheme is the first bad point. The second is using MD5 – while its brokenness for collisions doesn't affect password hashing, it is still bad, at least for your reputation. The third (and main) point is that your scheme is too fast to brute-force. Rainbow tables are not the way one attacks salted password hashes, brute-force (aka dictionary attacks) is, and it is entirely practical for typical users' passwords and your scheme. Look at What makes a hash function good for password hashing?. $\endgroup$ Commented Aug 5, 2013 at 19:12

1 Answer 1


Security against attacks using rainbow tables requires using a salt. In your first step $A_1 = MD5(P || S)$, you're already mixing in a salt. Provided that the salt is indeed globally unique (and randomly generating the salt is a correct way of achieving that), you already have protection against rainbow tables.

In a nutshell, rainbow tables trade off a huge amount of pre-computation for the ability to crack many hashes quickly. As soon as you use a salt, a useful rainbow table would have to accommodate for all possible salt values, which very quickly becomes impractical. For more information, read What are rainbow tables and how are they used?

There is nothing to be gained by mixing the salt in again through another application of MD5. However, if you repeated the process many times, you would achieve another property that is necessary for a password hashing function, namely that it must be slow, because that hurts the attacker far more than the defender. On this topic, do read How to securely hash passwords?

So if instead of using $A_2$ you used $A_{10000}$ (or however many iterations would be reasonable based on current CPU speeds), you would have what looks like a reasonable password hashing scheme, built along the same lines as PBKDF2, which is one of the recognized good password hashing functions. However, in cryptography, details matter. Maybe what you're doing is as good as PBKDF2, or maybe it has a fatal flaw that isn't immediately obvious to me. It would take a long time of analysis by multiple expert cryptographers to determine whether your password hashing function is acceptable.

Therefore, don't roll your own: use a generally-approved password hashing function. There are three big names: scrypt, bcrypt and PBKDF2. Scrypt is the new and improved thing, bcrypt is tried and tested, and PBKDF2 is showing signs of age, so bcrypt and scrypt are slightly preferable, but even PBKDF2 isn't fundamentally wrong. All three have PHP implementations available.


Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.