Why you need a special algorithm for passwords
When a user creates a password, you should never store the password itself — you store a hash of it. When they log in, you hash their input and compare it to the stored hash.
The problem: not all hashes are created equal for this purpose. A general-purpose cryptographic hash like SHA-256 is designed to be fast — it can hash millions of values per second on modern hardware. That speed is the enemy of password security.
If your database is breached and an attacker gets your stored hashes, they can try billions of password guesses per second against a SHA-256 hash. The entire list of common passwords, every word in every dictionary, and many short random strings can be tested in minutes on a modern GPU.
Bcrypt's key innovation: deliberate slowness
Bcrypt was designed in 1999 by Niels Provos and David Mazières specifically as a password hashing function. Its key design goal: be configurable slow.
Bcrypt introduces a cost factor (also called work factor) — an integer that controls how many iterations the algorithm runs. Each increase of 1 in the cost factor doubles the computation time:
- Cost 10: ~100ms per hash on a modern server
- Cost 12: ~400ms per hash
- Cost 14: ~1.6 seconds per hash
For a legitimate user logging in, waiting 100–400ms is imperceptible. For an attacker trying billions of guesses, that 100ms per attempt means ~10 guesses per second instead of billions. A billion-guess attack that takes 1 second against SHA-256 takes 3 years against bcrypt cost 10.
What a bcrypt hash looks like
A bcrypt hash is always 60 characters long:
$2b$12$eImiTXuWVxfM37uY4JANjQ.VedKfP9mYGCvbdGLMhfD6z0yXkQxYWThe parts:
$2b$— algorithm version (2b is current)12$— cost factor (12 here)- Next 22 characters — the salt (random, generated automatically)
- Final 31 characters — the actual hash
The salt is embedded in the hash itself — you do not need to store it separately. This also means two hashes of the same password will be different (different random salts), which prevents rainbow table attacks.
The salt: why the same password hashes differently every time
A salt is a random value added to the input before hashing. Bcrypt generates a new random 128-bit salt for every hash operation.
Without salts: if two users have the password "abc123," their hashes are identical. An attacker who cracks one cracks both. Pre-computed rainbow tables (massive lookup tables of password→hash mappings) work instantly.
With salts: "abc123" + salt_A produces a different hash than "abc123" + salt_B. Every hash is unique. Rainbow tables are useless.
Choosing the right cost factor
The right cost factor is the highest value where hashing stays under your acceptable response time — typically 100–300ms for a login endpoint.
- Most applications use cost 10–12
- High-security applications use 12–14
- As servers get faster, incrementing the cost factor keeps pace — this is why the factor is configurable
Test bcrypt at different cost factors using the free bcrypt generator and verifier — it shows the hash output and lets you verify a password against a stored hash.
Bcrypt vs SHA-256 for passwords
SHA-256 should never be used to hash passwords, even with a salt. The reason is speed: a GPU can compute 8 billion SHA-256 operations per second. A bcrypt at cost 12 is limited to about 250 per second on the same hardware. The difference is 32 million to 1.
Bcrypt vs Argon2
Argon2 is the winner of the Password Hashing Competition (2015) and is the current recommended algorithm. It is memory-hard in addition to being computationally slow — GPU and ASIC attacks that excel at computation are less effective when they also need large amounts of memory per guess.
If you are building a new system, prefer Argon2id. For existing bcrypt implementations, there is no urgent need to migrate — bcrypt is still secure when used correctly.
Summary
- Bcrypt is deliberately slow — each increase in cost factor doubles computation time
- It generates a random salt automatically and embeds it in the hash
- Always use a cost factor of at least 10 for production
- Never use SHA-256, MD5, or any fast hash for passwords
- For new systems, consider Argon2id instead
- Test and generate hashes with the free bcrypt tool