Bcrypt: Hash Passwords with Salt and Slowness
Bcrypt salts and slows every password hash so identical passwords never look the same and brute force stays expensive. Use it in register and login routes before the database. Never compare hashes with plain string equality; always call bcrypt.compare().
WHY IT EXISTS: Passwords are secrets that users reuse across sites. If a database leaks and you stored passwords in plain text or with a fast algorithm like SHA-256, attackers can crack millions of accounts in hours with a GPU. Bcrypt was designed to make offline brute force prohibitively expensive by being intentionally slow and memory-friendly, so that stealing a hash does not mean stealing the password.
THE MENTAL MODEL: Think of bcrypt as a gym membership with an adjustable monthly fee. The cost factor is the fee. When computers get faster, you raise the fee to keep the attacker sweating. Every password gets its own random salt, which means two users with the password password123 end up with completely different hashes. An attacker cannot precompute rainbow tables and must attack each hash individually.
HOW IT WORKS: Bcrypt takes a plaintext password, generates a random 16-byte salt, and runs the Blowfish-based key derivation circuit for a number of rounds determined by the cost factor. The output is a single string that encodes the cost, the salt, and the hash itself. In Node.js, you call bcrypt.hash(plainPassword, saltRounds) where saltRounds is typically between 10 and 13. A round count of 10 takes roughly a tenth of a second on modern hardware. To verify, bcrypt.compare(plainPassword, hash) extracts the cost and salt from the stored hash and re-derives the digest to check for a match.
WHEN TO USE IT: Use bcrypt any time you store user credentials for local authentication. It belongs in the user registration flow before the password ever reaches persistent storage, and again in the login flow before you issue a session or JWT. It is the default recommendation in the OWASP Cheat Sheet for password storage.
WHEN NOT TO USE IT: Do not use bcrypt for data integrity, file checksums, or signing API requests. It is not a general-purpose hash like SHA-256; it is specifically a password hash. Avoid it if you need verification to take less than a millisecond, because the slowness is the feature. Also do not roll your own salt generation; the library handles entropy better than Math.random() ever could.
ONE CANONICAL EXAMPLE: In an Express app, a POST /register route receives req.body.password. You await bcrypt.hash(req.body.password, 12) and store the resulting string in the password column. Later, a POST /login route retrieves the stored hash for the user, then awaits bcrypt.compare(req.body.password, storedHash). If the result is true, you authenticate the user. If you had used storedHash === await bcrypt.hash(...) you would generate a new salt and produce a guaranteed mismatch, leaking timing information and breaking security.
Get five bites like this every day.
Tezvyn delivers a daily feed of 60-second tech bites with quizzes to lock in what you learn.