When a website stores your password, the right approach isn't to save the password itself — or even a SHA-256 hash of it. The right approach is bcrypt. Designed in 1999 specifically for password hashing, bcrypt remains one of the most widely deployed password security algorithms today. Here's how it works and why it's so much better than simple hashing.
The problem with hashing passwords with SHA-256
SHA-256 is extremely fast — that's great for verifying file integrity, but catastrophic for storing passwords. A modern GPU can compute billions of SHA-256 hashes per second.
Consider what this means after a database breach: an attacker who steals a SHA-256 hash of your password can test billions of password guesses per second. Common passwords fall in milliseconds. Even an 8-character random password with mixed characters might crack in hours. The math simply doesn't favour defenders.
The solution is deliberate slowness — making each password attempt take a meaningful amount of time, not nanoseconds.
What is bcrypt?
bcrypt is a password hashing function designed by Niels Provos and David Mazières in 1999. It's based on the Blowfish cipher and designed with two key properties that SHA-256 lacks for password use:
- Adjustable work factor — You can make bcrypt slower as hardware gets faster, keeping it resistant to brute-force attacks indefinitely.
- Built-in salting — bcrypt automatically generates and stores a unique random salt for each password, making precomputed rainbow table attacks useless.
The cost factor (work factor)
The bcrypt cost factor is a number (typically 10–14) that controls how computationally expensive each hash is. Specifically, bcrypt performs 2cost key expansion iterations:
At cost 12 (~400ms), a legitimate user logging in barely notices the delay. But for an attacker trying billions of guesses: 400ms × 1 billion = 12.7 years for a single GPU. Even a 100-GPU cluster would take months to crack a single strong password.
As CPUs and GPUs get faster, you simply increase the cost factor by 1 (doubling the work) to maintain the same time-per-hash. This is called adaptive hashing — the reason bcrypt designed in 1999 is still recommended in 2026.
The bcrypt hash format
A bcrypt hash looks like this:
$2b$12$LQv3c1yqBWVHxkd0LHAkCOYz6TtxMQJqhN8/LeKQqE6VQlF.TtTx2
Breaking it down:
$2b$— Algorithm identifier (bcrypt v2b)12— Cost factor (2¹² = 4,096 iterations)LQv3c1yqBWVHxkd0LHAkCO— 22-character salt (128 bits, Base64-encoded, randomly generated)Yz6TtxMQJqhN8/LeKQqE6VQlF.TtTx2— 31-character hash output
The salt is embedded in the hash string, which makes bcrypt self-contained — you only need to store one string per user password.
bcrypt vs Argon2 vs scrypt
| Algorithm | Year | Memory-hard? | GPU resistance | Recommendation |
|---|---|---|---|---|
| bcrypt | 1999 | No | Moderate | ✅ Still widely used & safe |
| scrypt | 2009 | Yes | Good | ✅ Good, less adoption |
| Argon2id | 2015 | Yes | Excellent | ✅ Best for new systems |
| PBKDF2 | 2000 | No | Poor | ⚠️ Acceptable, weaker |
| SHA-256 (raw) | 2001 | No | None | ❌ Never for passwords |
Argon2id (winner of the 2015 Password Hashing Competition) is the modern recommendation for new systems. It's memory-hard — GPU attacks are far less effective because each attempt requires significant RAM, limiting parallelism. However, bcrypt is still secure if used with cost ≥ 12 and remains the most widely deployed option.
bcrypt limitations to know
- 72-character limit — bcrypt truncates input at 72 bytes. Passwords longer than 72 bytes don't add security. Some implementations pre-hash the password with SHA-256 before bcrypt to handle long passwords safely.
- Null byte handling — Some implementations stop at the first null byte. If your password contains a null byte (\0), verify your library handles it correctly.
- Not memory-hard — Unlike Argon2 and scrypt, bcrypt can be efficiently parallelized on GPUs for moderate cost factors. Use cost ≥ 12 (ideally 13–14 for new systems) to compensate.
What developers should use
- New systems (2024+): Argon2id (memory: 64MB, iterations: 3, parallelism: 4)
- Existing bcrypt systems: Keep bcrypt at cost ≥ 12, increase to 13-14 if performance allows
- Never use: MD5, SHA-1, SHA-256, SHA-512, or any fast hash directly for passwords
Frequently asked questions
Why does bcrypt have a 72-character limit?
The 72-character limit comes from the underlying Blowfish cipher's key schedule, which processes only the first 72 bytes of input. This is a known limitation. If your application accepts very long passwords (passphrases), consider pre-hashing with SHA-256 before bcrypt to safely handle arbitrary-length inputs.
Is bcrypt safe against GPU attacks?
Bcrypt offers better GPU resistance than SHA-256 because it was designed for CPU execution, not GPU parallelism. However, it's not memory-hard — GPUs can still run bcrypt in parallel with sufficient VRAM. At cost 12-14 on modern hardware, cracking a strong bcrypt hash still takes days to months per GPU, making it computationally infeasible for well-chosen passwords.
How often should bcrypt cost factors be increased?
OWASP recommends increasing the cost factor whenever hash computation drops below 100ms on current hardware. In practice, review and potentially increase the cost factor every 2-3 years as hardware improves. Most frameworks make this easy — bcrypt automatically handles re-hashing at a higher cost when users next log in.