Last blog post I mentioned that you should never store passwords in plain text on a server. Actually, you shouldn't store passwords in plain text on any computer, including servers. Here's why you shouldn't, and what you should do instead when writing a server.
Why Not Plain Text Passwords on the Server?
Data breaches. They happen far too often. Do a quick internet search for "data breaches," and you'll see plenty of them.
If someone manages to steal a plain text password database, then it's game over. They can log into every single user account on the system. Data breaches happen, so you want to limit the potential damage as much as possible.
What About Encrypting the Passwords?
Encrypting the passwords is a step up. However, if a hacker manages to steal the encryption key, then they've still compromised all user accounts. There's got to be a better way...
Solution: Cryptographic Hashing Functions
The solution is to never store passwords on the server. But, the server needs to compare user logins to their passwords. How can we do that without storing the password on the server? Answer: cryptographic hashing functions.
Cryptographic hashing functions transform a string to a fixed-length "message digest" (a.k.a., hash) They have two important properties:
- The hash is as unique as possible (i.e., different input strings are extremely unlikely to result in the same hash)
- The function is "one way," or practically irreversible. Unlike encryption algorithms, it should be impossible to be able to calculate the original string (e.g., password) from the hash
Here's how hashing helps:
- The server stores the password's hash instead of the password. So there's no password for anyone to steal. Stealing the database of hashes won't give anyone access
- When a user logs in, compare the hashed password with the password hash stored in the user database. If they match, then the user can log in
Problem solved. The password isn't stored on the server, but the server can still confirm whether a user's password is correct. We're not done yet, though...
Salting the Passwords
Storing password hashes prevents would-be hackers from getting everyone's passwords, but there's still a problem. If multiple users choose the same password, then they'll have the same hash. So, a hacker could glance down the password hash table, and spot everyone with the same password. Cracking that one password would give them access to multiple accounts.
Even worse, hashes of known/common passwords could easily be compared to the password database. This is called a rainbow table attack. Any accounts whose hashes get matched to rainbow table entries are compromised.
The answer is to salt the passwords before. Salting is a fancy term for adding some random characters to the password. This is done before hashing, and ensures that each password + salt combination is unique even if the password is not. The server stores both the salt and the hash, so that incoming logins can be compared with the salted hash.
If you're writing a server, follow current best practise. Store passwords salted and hashed. Look up what hash functions are currently recommended, since older ones may have known flaws which could once again expose passwords if the hashes are stolen.