Complete Guide to Bcrypt Password Hashing
Bcrypt has been the cornerstone of secure password storage for over two decades. Developed by Niels Provos and David Mazières in , this algorithm remains one of the most trusted methods for hashing passwords. This comprehensive guide explains why our bcrypt generator produces hashes that remain secure against modern attacks, and how to implement bcrypt correctly in your applications.
The Problem Bcrypt Solves
Fast hash algorithms like MD5 and SHA were designed for speed—verifying file integrity, creating checksums. This speed becomes a liability for passwords. Modern GPUs can compute billions of SHA-256 hashes per second , making brute force attacks frighteningly practical.
Bcrypt flips the script. By incorporating an expensive key setup phase based on the Blowfish cipher, bcrypt deliberately slows down hashing. What takes microseconds with SHA-256 takes hundreds of milliseconds with bcrypt. An attacker who could try 10 billion SHA guesses per second might only manage 10,000 bcrypt guesses—a million-fold reduction in attack speed.
Understanding the Cost Factor (Salt Rounds)
The cost factor (also called work factor or salt rounds) determines how computationally expensive hashing becomes. It's a power of 2: cost 10 means 2^10 = 1,024 iterations of the key derivation function. Each increase doubles the time required. Cost 10 might take 100ms; cost 11 takes 200ms; cost 12 takes 400ms.
Choose your cost factor based on your production hardware, targeting 250-500ms per hash . Yes, that seems slow for login, but users won't notice the difference, and it devastates attackers. Increase the cost factor over time as Moore's Law provides faster hardware. Start at 10-12 for most applications today.
Automatic Salting Explained
Bcrypt automatically generates a 128-bit random salt for each password. This salt is stored as part of the hash string itself, so you don't need to manage salts separately. When verifying, bcrypt extracts the salt from the stored hash and uses it to hash the candidate password.
Salting defeats rainbow tables—precomputed tables mapping common passwords to their hashes. Without salts, attackers could look up "password123" → hash instantly. With unique salts, they'd need a separate rainbow table for each user—computationally infeasible. Even if two users share the same password, their bcrypt hashes will differ.
Common Bcrypt Mistakes to Avoid
- ❌ Using a cost factor that's too low
- Cost factors below 10 are too fast on modern hardware. Attackers can crack millions of hashes quickly. Always benchmark on your production servers and aim for 250-500ms.
- ❌ Truncating passwords before hashing
- Bcrypt has a 72-byte limit on password length. If users can enter longer passwords, consider pre-hashing with SHA-256 first, or use Argon2 instead.
- ❌ Storing hashes with the wrong encoding
- Bcrypt hashes are ASCII strings. Don't base64-encode them again or store them as binary. The hash string includes everything needed for verification.
- ❌ Not handling timing attacks
- Use constant-time comparison functions provided by bcrypt libraries. Never compare hashes with
==in languages where this isn't constant-time.
Implementation Best Practices
Always use your language's standard bcrypt library rather than implementing yourself—subtle bugs can compromise security. Most modern frameworks include bcrypt: PHP's password_hash(), Python's bcrypt library, Node's bcrypt package. Never store plain-text passwords, even temporarily. Generate strong passwords and verify their strength before hashing.
Plan for cost factor increases. Store the hash (which includes the cost factor) and periodically rehash on successful logins when you raise the cost. This migrates users seamlessly to stronger protection. Enforce password policies so bcrypt doesn't have to protect weak passwords alone.