How passwords should be stored in a database
plaintext password risks, hashing vs encryption, bcrypt algorithm, salt, work factor, rainbow table attacks
Never Store Plaintext Passwords
If your database leaks and passwords are stored in plaintext, every user account is instantly compromised. This is not theoretical โ it has happened to major companies. Your job is to make a leaked database useless to an attacker.
Hashing vs Encryption
Encryption is reversible โ if you have the key you can get the original value back. For passwords, that is a problem. Hashing is one-way. You cannot reverse a hash to get the password back. During login, you hash what the user typed and compare it to the stored hash.
Do not use SHA-256 or MD5 for passwords. They are designed to be fast, which makes brute-force attacks trivial. Use bcrypt, argon2, or scrypt โ algorithms designed to be deliberately slow.
Salt and Work Factor
A salt is a random string added to a password before hashing. It ensures two users with the same password produce different hashes, defeating rainbow table lookups.
bcrypt handles salting automatically. The work factor (cost factor) controls how slow the hash computation is. A higher value means more security but more CPU time.
const bcrypt = require('bcrypt');
const SALT_ROUNDS = 12;
// Hashing during registration
const hash = await bcrypt.hash(plainPassword, SALT_ROUNDS);
// Comparing during login
const isMatch = await bcrypt.compare(plainPassword, storedHash);
console.log(isMatch); // true or false
Start with a work factor of 12. Increase it as hardware gets faster.
