How bcrypt Keeps Passwords Safe (and Why Not to Use SHA-256)
If you store user passwords, the way you hash them is the difference between "a breach is embarrassing" and "a breach is catastrophic." The instinct is to reach for SHA-256 — it is a hash, after all. That instinct is wrong, and understanding why is one of the most useful things a developer can learn.
Encoding, hashing, encryption — three different things
- Encoding (Base64) is reversible by anyone; it hides nothing.
- Encryption is reversible with a key.
- Hashing is one-way: you cannot recover the input from the output.
Passwords must be hashed, never encrypted, because you should never be able to recover a user's password — not even you. But which hash matters enormously.
Why SHA-256 is the wrong tool
SHA-256 is designed to be fast — that is a feature for file integrity and signatures. For passwords it is a disaster. Modern hardware computes billions of SHA-256 hashes per second. If your database leaks, an attacker runs a dictionary or brute-force attack against the stolen hashes at that speed and cracks weak passwords in seconds.
Passwords need a hash that is deliberately slow and tunable, so you can keep raising the cost as hardware improves. That is exactly what bcrypt is.
What bcrypt does differently
1. A built-in salt. bcrypt generates a random salt for every password and stores it inside the hash. Two users with the same password get completely different hashes, which defeats precomputed "rainbow table" attacks. You never manage salts yourself.
2. A cost factor. bcrypt runs an expensive key-setup step 2^cost times. A cost of 10 means 1,024 rounds; 12 means 4,096. Each increment doubles the work. You tune it so a single hash takes ~100–250 ms — trivial for one login, ruinous for an attacker trying billions.
Reading a bcrypt hash
A bcrypt hash looks like:
$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW
$2b$— the algorithm/version12— the cost factor- next 22 chars — the salt
- final 31 chars — the hash
Because the salt lives in the string, verifying a password never "decrypts" anything: you hash the entered password with the stored salt and compare. You can see this in action — generate and verify hashes with the bcrypt tool.
Two limits to know
- The 72-byte cap. bcrypt only uses the first 72 bytes of input. For long passphrases, pre-hash with SHA-256 first, then bcrypt the result.
- Client-side is for learning only. In a real system, always hash on the server. A browser tool like ours is for development, testing, and understanding — never wire it into a production login.
When to use Argon2 instead
For brand-new systems, Argon2id is the current state of the art. Unlike bcrypt, it is also memory-hard, which resists attackers using GPUs and custom hardware. bcrypt remains a completely safe, battle-tested, widely-supported choice — but if you are starting fresh and your platform supports it, Argon2id is the modern default.
The bottom line
Never hash passwords with a fast, general-purpose hash. Use a slow, salted, tunable password hash — bcrypt or Argon2id — with a cost calibrated to your hardware. Get this one decision right and a database breach stops being the end of the world.