Skip to content
tezvyn:
Menu

Bcrypt: Hash Passwords with Salt and Slowness

MediumHow cards are made

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.

Interview question

An attacker steals a database of bcrypt hashes. Which feature most directly forces them to crack each hash individually instead of using precomputed rainbow tables?

  • a.The cost factor makes each hash computation intentionally slow
  • b.Each hash is generated with a unique random saltCorrect
  • c.bcrypt.compare re-derives the digest rather than doing direct string matching
  • d.The output string encodes the cost, salt, and hash together
Why?

A unique random salt ensures identical passwords produce completely different hashes, rendering precomputed rainbow tables useless. While the cost factor (A) slows brute-force attempts, it does not prevent precomputation; salting does.

Just read this? Test yourself on what you have been reading.

Put your scrolling time to good use

Learn one idea, try a quiz and save useful cards for revision. Tezvyn makes it easy to learn and stay current in your tech field, a few minutes at a time.

The iPhone app is on the way

We are building it. Until it lands, nothing here is held back from you: every interview card, your saved cards, streaks and the job board all work in Safari, plus hundreds of free practice quizzes of thirty questions each. Sign in and it all carries over to the app the day it arrives.

Want it as an icon? Tap Share at the bottom of Safari, then Add to Home Screen. It opens full screen and the cards you have read stay available offline.

Get it on Google PlayiPhone app coming soon

We are hiring for this. Every open role lists the topics its interview covers, so you can prepare for the real thing rather than guessing.

See open roles