On March 21, 2019, Facebook announced that it had exposed hundreds of millions of their users’ passwords. A bug in its password management systems caused passwords for Facebook, Facebook Lite, and Instagram to be stored as plaintext in an internal platform. As a result, thousands of Facebook employees could have potentially seen them. Krebs reports that the exposed passwords included those going as far back as 2012.
Have you ever lost your password and requested a help, resulting in the company giving your your password in an email? This means they either stored your password in a two-way (asynchronous) encryption algorithm, like blowfish, or they actually didn’t encrypt your password at all. Yikes!
Storing plaintext passwords, even offline, is never a good idea — even if it’s temporary, e.g., during a signup process.
Having said that, here are several methods of storing passwords, each with their pros and cons.
1. Plain Text
This is a naive method of storing passwords on a server as raw text.
You can show the user their password (hopefully over a secure connection) if they forget it. Again, this is not recommended at all.
If anyone gets their hands on the database, they see everyone’s password. Since people often use the same password for different websites, they could get access to other accounts as well.
Too risky. Never store raw passwords, even temporarily. Protect your members and avoid legal liability.
Encryption usually involves a key to lock up the password. The same key could be used to unlock the password. Since the password is unlockable, it shouldn’t take much work to unlock the password. When a user logs in, the password is decrypted and compared to the password the user submitted.
Slightly better than plain text.
As soon as the key is made available, it can be used. Keys can be intercepted on insecure connections or in other ways. People who use the same password will have the same encryption code.
While encryption is still better than storing raw text, it’s highly discouraged.
If somebody gets access to the database, they likely also can see your username or email address and can not only log in on the compromised site, but possibly other sites.
Hashing is basically a summary of a bunch of data. The result is a short byte array or string that can represent your password. Some hashing algorithms are better than others. To validate the user, hashes are compared rather than actual passwords.
Cracking is very difficult for most hashing algorithms.
Some hashing algorithms, like md5, have been cracked. There’s the same problem with encryption where the resulting code is the same. This means the same passwords have the same hash. Hashes can be searched online and will give you the password.
Hashing, even with very secure hashes like sha256, should be avoided. Even strong hashing algorithms will result in the same hash for the same password.
4. Hashing with Peppering
A salt is usually a string that’s appended to all passwords before hashing. E.g., instead of hashing “abc123”, you would hash “abc123pluto”, where “pluto” is added to all passwords. This method is much better than mere hashing, and makes existing tables that have pre-cracked hashes almost useless. Usually, cracking a peppered hash requires a lot of work.
Safer than hashing alone. Makes the use of rainbow tables more less fruitful.
As with (2) and (3), hashes for the same passwords will all be the same.
Since the same hash is used in all passwords, this a hacker doesn’t need much more effort to crack all of the passwords in a database than just cracking the password alone.
5. Hashing and Salting
Unlike peppering, salting is a random string or bytes that are appended to a password before its hashed. Since it’s random, a different salt will be used for each stored password.
Salting makes a hash far more secure than peppering, especially when multiple passwords are used in a database.
The pepper must be stored somewhere so that it can be used when comparing hashes.
Peppering hashes was very common a few years ago. The randomness added a significant obstacle to hackers. This method is fairly secure, but yet another step can be taken.
6. Hashing, Salting, and Re-Hashing
This is the standard as of today. The password is not only salted and hashed, but then it’s re-hashed again (the hash output is used as the hash input). This can not only be done many times, but the number of times can, and should, be random. As with the salt, the number of rehashes will also have to be saved somewhere.
Adding work via rehashing — especially with random iterations — makes the hash harder to crack. The more the work (rehashes) added, the harder it is to crack.
More iterations means a more secure password, but more work for the server to perform the has as well.
Using a good hashing algorithm, a very random hash, and a very random number of rehashes, you should end up with an extremely secure password. This is the current industry standard. Some hashing algorithms, save the algorithm type, work, and pepper in the hash itself. This makes for easy storage.
Avoid creating your own hashing algorithm. There are many excellent hashing and verification methods for all kinds of languages for you to use. A good example is PHP’s hash_password() which does all the work above for you!