Let’s talk about security and how to store passwords. This can be a fairly involved subject, but we can start at the beginning. Let’s ask the question at the highest level: how do people log in? And how can we store credentials so that our users log in securely?
The Insecure Way
Here is one workflow for the login process, let’s call it “The Completely Insecure Way”
- Precondition: Passwords are stored in plain text in the database
- The user types in a username and password to a web browser
- The server receives this password
- The server compares it directly against the password stored in the database
- If they are the same, the user entered the correct password and may continue
For the love of all that is good, please don’t ever do this!
Why is the insecure way insecure? Because if an attacker is able to access your database, they can see and use every password in the system. “Ok” you say “But my system is the backend for an app that makes fart sounds, it doesn’t store credit cards or anything. It’s inconvenient but not the end of the world if I lose control of those passwords.” Actually, this is extremely dangerous. Not only does the attacker have access to data on your system, it is likely that some users re-use the same passwords across multiple systems. They should not, but some do! If an attacker had access to a set of passwords linked to email addresses, they could just make the rounds on banking systems to try logging in with those same credentials. The results could be disastrous.
So, how can we safely store passwords to allow people to log in?
The More Secure Way
Here is another workflow for the login process, let’s call it “The More Secure Way”
- Precondition: All passwords are encrypted, and only the encrypted text is in the database
- The user types in a password
- The server receives this password and immediately encrypts it
- The server compares this encrypted password against the encrypted password in the database
- If the encrypted text matches, the original passwords must also match, so the user entered the correct password and may continue
I’m skipping a lot of details about how the actual encryption happens and various things to keep in mind, but this is just a high level overview.
This is more secure because if an attacker manages to access your database, they can NOT see and use every password in the system. They just see garbled text instead of a usable password. They could still try to brute-force hack the passwords (encrypting every possible password until they accidentally find a match) but this takes much longer and is much more difficult.
Never ever ever store passwords in plain text in your database. Always store them encrypted.