How to Store Passwords Safely (and Not Regret Later)
Okay, today I want to talk about something basic but extremely important — storing passwords in your database.
Now, before you think, “Ah, I already hash passwords, what’s the big deal?” — hear me out. Because I've seen this being done wrong way too often, and once you go down that path, it can be difficult to recover.
What not to do (a.k.a. please don't be this developer)
Let me start by stating the obvious — never store passwords as plain text.
Sounds simple, right? Yet I’ve seen production systems that still do it. If someone internally gets access to your DB, or worse, if it leaks — everyone’s credentials are just sitting there. Not cool.
Now you might think, “Alright, I’m smart, I hash them.”
Good start, but here’s the thing — just hashing alone isn’t enough either. Hashes without salt are still vulnerable. There’s this thing called rainbow tables — precomputed hash databases — that can reverse your hash like it’s magic.
So unless you want your users’ “password123” to be cracked in 0.3 seconds, read on.
Enter: salt 🧂 (no, not the kitchen one)
So here’s where we improve things. We add salt to the hashing process.
What’s salt? OWASP puts it nicely:
“A salt is a unique, randomly generated string that is added to each password as part of the hashing process.”
In other words, it’s a little extra randomness that makes even common passwords look unique after hashing. So even if 10 users use the same password, their final hashes are completely different.
This means attackers can’t just rely on rainbow tables anymore — they’d have to recompute everything for every salt. Makes things significantly harder for them.
How to actually store passwords safely
Here’s the simple flow — and believe me, it’s not rocket science.
1️⃣ When the user signs up, you generate a random salt.
2️⃣ You append the salt to the password and hash the result.
3️⃣ Store both the salt and the hash in the database.
Just to be clear — the salt is not a secret. It can be stored as-is in the DB.
But it's crucial to the security of the final hash.
Example schema:
{
"username": "janedoe",
"salt": "f1nd1ngn3m0r4nd0m",
"hashedPassword": "a379fbc8e53a9... (you get the idea)"
}
The hash might be generated as something like:
(password + salt)
And no — don’t just use MD5
or SHA1
. Please use strong algorithms like bcrypt, scrypt, or Argon2 — stuff that’s designed to be slow on purpose, making brute-force attacks expensive.
How do we validate passwords?
During login:
- User enters their password.
- You fetch their salt from the DB.
- Recompute the hash using:
hash(password + salt)
- Compare it with the stored hash.
If they match, we’re good. If not, it’s a no-go.
Conclusion
If you’re handling passwords — even for a tiny project — please treat them with the respect they deserve. Security isn’t something we slap on later. It starts from the very first line of code that handles user data.
Keep it simple, keep it safe.
And hey — if you’ve stored passwords the wrong way in the past (we all have) — now’s a great time to fix it.
Member discussion