password hashing with bcrypt: why plain storage is catastrophic
plaintext password risks, one-way hashing, bcrypt algorithm, salt rounds, bcrypt.hash, bcrypt.compare, timing attacks, cost factor tuning
Password Hashing with bcrypt
Never store passwords. Store hashes. This is non-negotiable โ database breaches happen, and plaintext passwords compromise users across every site they reuse that password.
bcrypt is the standard choice. It is deliberately slow (making brute-force expensive), generates a random salt per hash (preventing rainbow table attacks), and bundles the salt into the output string.
const bcrypt = require('bcrypt');
// Hashing on registration
const saltRounds = 12;
const hash = await bcrypt.hash(plainPassword, saltRounds);
// Store `hash` in DB, discard plainPassword
// Verifying on login
const isMatch = await bcrypt.compare(inputPassword, storedHash);
// Returns true or false โ bcrypt extracts the salt automaticallySalt rounds (also called cost factor) control how slow hashing is. 10 is the old default; 12 is the current practical minimum for new projects. Higher = slower to hash but also slower for attackers. At 12, each hash takes ~250ms on modern hardware โ acceptable for login, prohibitive for bulk attacks.
Never implement your own hashing. MD5 and SHA-1 are not password hashing algorithms โ they are fast by design, which makes them useless here. Use bcrypt, argon2, or scrypt. bcrypt has the widest ecosystem support in Node.js.
