I have a system that stores passwords encrypted, with a one-way algorithm (meaning that in most cases, it's nigh-impossible to get the password back from what is stored).
e.g. "password" becomes 286755fad04869ca523320acce0dc6a4i (the "hash"), but given what's stored in the database: 286755fad04869ca523320acce0dc6a4, it's almost impossible for anyone to know that the password is "password". So if the database is stolen, no one can read the passwords. (That hash was possibly generated with a newline.)
When someone registers their account, the password they type is stored as a hash. When they log in, the password they type is hashed and compared (along with the login) with the database. Match, means they are who that database record says they are, and can log in.
Problem: there are available "rainbow tables". These are huge computer-generated lists of common words and phrases that people use as passwords. All an attacker has to do is compare the tables with the database, and see that the database contains 286755fad04869ca523320acce0dc6a4 and the table maps that to "password". The username and email are there already, so now they can try this info at a banking site. Most people use the same or similar passwords everywhere.
These attacks have happened on other sites.
A solution: instead of hashing "password", combine it with something else like
"s3cret". This is called a salt. So now we hash "s3cretpassword". If someone's password is swordfish,
we hash "s3cretswordfish". The hash for both of these is:
Of course we choose something a little more complicated than s3cret. So generating rainbow tables using all possible salts is impossible, so we're back to storing in the database an impenetrable string, which is also unique to our site. So someone who has stolen our database (it happens, not to us because we don't leave our database on thumb drives and laptops) will not be able to decrypt even lame passwords like "password". Our password checker does not even allow "password" but now there is an extra and better layer of security.
So, we have:
- salted passwords against rainbow table attacks
- password strength requirement (which security experts say is lame, and I agree, because it actually reduces the number of possible passwords, making automatic guessing easier. And also encourages people to use the same password everywhere, and write it down, etc.)
- and password guess throttling (you get locked out temporarily after a small number of bad logins) to defend against automatic guessing.