Hopefully everyone knows that storing passwords in plain text is very bad idea. That one should be obvious. What’s not so obvious is that not all hashing algorithms are safe.
One of the least safe and unfortunately the most widely used is MD5. SHA1, although in theory a little safer is just as bad. The problem with these algorithms is that they are fast, they are designed that way, but unfortunately many books and tutorials still use them. For example, an average computer with fast GPU could crack about 8 billion MD5 hashes or 3 billion SHA1 hashes each second. To put this into perspective, a 6 character password made of random letters, single case, has about 300 million possible combinations.
There are techniques used to make these insecure algorithms more secure. Adding salt for example is good protection against rainbow tables, but it does little to protect against brute force attacks. Key stretching and peppering appear to be better, but in the field of security appearances are not good enough. As Bruce Schneier said:
“Anyone, from the most clueless amateur to the best cryptographer, can create an algorithm that he himself can’t break.”
Reinventing the wheel is bad, especially in cryptography. Hash functions were designed for signing and they are designed to be fast. Implementing them for hashing passwords is therefore bad idea even if peppering is applied. GPU attacks are one of the reasons for this, they can calculate hashes fast, but they are not effective with bcrypt.
To store passwords securely, use Password Hashing API. It is available since PHP 5.5 and it’s easy to use. Bare in mind that the 60 character long hash string may expand in future and that manually specifying salt will be deprecated in PHP 7.0.
Now, why is this so important? You might be thinking that your database is secure and that by imposing password length and complexity requirements, you made your users use secure passwords. The problem is that no database is perfectly safe and more importantly – we humans can’t generate secure passwords. Even something like a passphrase made of 5 random words has only 30 bits of entropy which is really insecure. And finally, if you are thinking that you don’t have to worry about your users’ passwords being cracked because your web service is not very important, think again. Password reuse is a big problem, many of your users will be using the same password for their email and other important accounts.