What Is bcrypt and Why You Should Use It for Passwords
· 6 min read
If you store passwords, how you store them matters more than almost any other security decision you make. The right answer for most applications is bcrypt, a password-hashing function designed specifically to resist brute-force attacks. Understanding why it works the way it does will keep you from making the most common and most dangerous mistake.
Never Store Passwords in Plain Text
This should be obvious, but breaches keep proving it isn't. You never store the raw password. Instead you store a hash, a one-way transformation that lets you verify a login without keeping the secret itself. When a user signs in, you hash what they typed and compare it to the stored hash. The catch is that not all hashes are suitable for this job.
Why Fast Hashes Are the Wrong Tool
General-purpose hash functions are built to be fast. That is exactly what you want for checksums and content addressing, and exactly what you do not want for passwords. The MD5 Hash Generator and SHA-256 Hash Generator are great for verifying file integrity or generating fingerprints, but a modern GPU can compute billions of MD5 or SHA-256 hashes per second. If an attacker steals your database, that speed lets them test enormous password lists almost instantly. MD5 is doubly disqualified because it is also cryptographically broken.
The defining feature of a password hash is that it should be slow, and adjustably so.
Salting Defeats Precomputation
Before hashing, bcrypt mixes in a salt: a random value unique to each password. Without salting, two users with the same password produce the same hash, and attackers can use rainbow tables - giant precomputed lookups - to reverse common passwords in bulk. A unique salt per user makes those precomputed tables useless, because the attacker would need a separate table for every salt. bcrypt generates and stores the salt for you, embedded directly in the output string, so you do not manage it separately.
The Work Factor
bcrypt's real power is its cost, also called the work factor. This is an integer, and the work doubles with each increment. A cost of 10 means 2 to the 10th rounds of internal hashing; a cost of 12 means four times as much work as 10. By turning a single dial, you make hashing deliberately expensive. A login that takes you a fraction of a second becomes a wall for an attacker trying billions of guesses, because every guess now costs them that same fraction of a second multiplied across the whole keyspace.
Because the cost is tunable, bcrypt ages gracefully. As hardware gets faster, you raise the cost to keep pace, rehashing users' passwords on their next login.
How to Choose a Cost
The right cost is the highest one your servers can tolerate without hurting the user experience. A common target is a hash time of roughly 250 to 500 milliseconds on your production hardware. On typical modern servers that lands around a cost of 11 to 13. Do not just copy a number from a tutorial - measure on your own infrastructure, since a value that is comfortable on a fast machine may be painful on a constrained one.
You can experiment with the trade-off using the bcrypt Hash Generator. Try the same password at different cost values and watch how the computation time climbs. It hashes entirely in your browser, so the password you test is never uploaded anywhere.
A Note on bcrypt's Limits
bcrypt only considers the first 72 bytes of input. For ordinary passwords this is irrelevant, but if you pre-hash long inputs or accept very long passphrases, be aware of the truncation. Newer alternatives like Argon2 and scrypt add memory-hardness, which resists GPU and ASIC attacks even better, and are worth considering for new systems. But bcrypt remains a solid, battle-tested default that is widely supported across languages and frameworks.
The Short Version
- Never store plain passwords; never use MD5 or SHA for them.
- Use a deliberately slow, salted hash - bcrypt is a safe default.
- Salts defeat rainbow tables; the work factor defeats brute force.
- Pick a cost that takes a few hundred milliseconds on your real hardware, and raise it over time.