Bcrypt Hash Generator
Hash and verify passwords with bcrypt — configurable cost factor, runs entirely in your browser
Higher rounds = exponentially more compute. Production default is 10–12.
You’re building a user authentication system and need to store passwords safely. You know you shouldn’t store plaintext or use MD5/SHA-256, but you need to verify that your bcrypt configuration is correct before shipping. Or you’re auditing a legacy system and want to confirm that a stored hash actually matches the original password. This tool hashes and verifies bcrypt passwords entirely in your browser — nothing is sent to any server.
Why Bcrypt and Not SHA-256 for Passwords?
SHA-256, SHA-512, and MD5 are general-purpose hash functions designed to be fast. “Fast” is exactly the wrong property for password hashing. A modern GPU can compute billions of SHA-256 hashes per second — meaning an attacker who steals your hashed password database can brute-force billions of password guesses every second.
Bcrypt is a password hashing function designed to be deliberately slow. It was created by Niels Provos and David Mazières in 1999 and is still the industry standard because of three key properties:
- Adaptive cost factor — the work factor (salt rounds) can be increased as hardware gets faster, keeping bcrypt secure even on modern hardware
- Built-in salting — bcrypt automatically generates a random salt for each hash, making rainbow table attacks impossible
- Output includes the salt — the hash encodes the salt, algorithm version, and cost factor, so you only need to store one string
The Salt Rounds (Cost Factor) Explained
The salt rounds parameter (also called the work factor) controls how computationally expensive the hash is. Each increment doubles the compute time:
| Salt Rounds | Approximate Time | Use Case |
|---|---|---|
| 4–6 | < 5ms | Testing and development only |
| 8 | ~25ms | Low-security, high-throughput systems |
| 10 | ~100ms | Production default — recommended |
| 12 | ~400ms | High-security applications (banking, healthcare) |
| 14 | ~1.6s | Maximum security, low traffic |
The bcrypt hash output encodes the cost factor ($2b$10$ means bcrypt version 2b, 10 rounds). When you verify a password, bcrypt reads the cost factor from the stored hash automatically — you don’t need to track it separately.
Choosing salt rounds for production: aim for 100–500ms hashing time on your production hardware. This is imperceptible to users logging in but makes brute-force attacks prohibitively expensive. Run benchmarks on your actual server hardware before deciding.
What the Bcrypt Hash Format Means
A bcrypt hash looks like this:
$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy
Breaking it down:
$2b$— bcrypt algorithm version (2b is the current standard; you may also see 2a or 2y in legacy systems)10$— cost factor (salt rounds = 10)N9qo8uLOickgx2ZMRZoMye— the 22-character base64-encoded salt (128 bits)IjZAgcfl7p92ldGxad68LJZdL17lhWy— the 31-character base64-encoded hash
The total hash is always 60 characters. Each time you hash the same password, a new random salt is generated, so you’ll get a different hash — but bcrypt.compare() will verify all of them correctly against the original password.
Bcrypt in Code
// Node.js with bcryptjs or bcrypt
import bcrypt from 'bcryptjs';
// Hash a password
const saltRounds = 10;
const hash = await bcrypt.hash('myPassword123', saltRounds);
// Store `hash` in your database — never store the plaintext password
// Verify on login
const isMatch = await bcrypt.compare('myPassword123', storedHash);
if (isMatch) {
// Password is correct — create session
}
# Python with bcrypt library
import bcrypt
# Hash a password
password = b"myPassword123"
salt = bcrypt.gensalt(rounds=10)
hashed = bcrypt.hashpw(password, salt)
# Store hashed.decode() in your database
# Verify on login
is_valid = bcrypt.checkpw(b"myPassword123", hashed)
// Go with golang.org/x/crypto/bcrypt
import "golang.org/x/crypto/bcrypt"
hash, _ := bcrypt.GenerateFromPassword([]byte("myPassword123"), 10)
err := bcrypt.CompareHashAndPassword(hash, []byte("myPassword123"))
// err == nil means correct password
Common Mistakes to Avoid
Don’t hash passwords with SHA-256/SHA-512: These are fast by design. Even with a salt added manually, they provide orders of magnitude less protection than bcrypt against GPU brute-force attacks. Use bcrypt, Argon2id, or scrypt for passwords.
Don’t use MD5 for anything security-related: MD5 is cryptographically broken. Collisions can be computed in seconds. It remains valid for non-security checksums (file deduplication, cache keys) but never for passwords or signatures.
Don’t set cost factor below 10 in production: A cost factor of 6 hashes in under a millisecond on modern hardware. That means an attacker with a leaked database can try 1,000+ passwords per second on a single CPU core.
Re-hash on login if cost factor is outdated: If you’ve increased your cost factor, check the hash prefix on each successful login and re-hash if the stored cost factor is lower than your current target.
Bcrypt vs. Argon2 vs. scrypt
| Algorithm | Salt | Memory-hard | Speed | Winner of PHC | Recommendation |
|---|---|---|---|---|---|
| bcrypt | Built-in | No | Configurable | No | Safe for most apps |
| scrypt | Built-in | Yes | Configurable | No | Good for high-security |
| Argon2id | Built-in | Yes | Configurable | Yes (2015) | Best for new systems |
Recommendation: Use bcrypt if your framework has battle-tested support for it (most do). Use Argon2id for new systems where you control the full stack — it won the Password Hashing Competition and is more resistant to GPU attacks due to its memory-hardness.
Frequently Asked Questions
Can I reverse a bcrypt hash? No. Bcrypt is a one-way function. The only way to “crack” it is by trying candidate passwords one at a time — which the high cost factor makes prohibitively slow. There is no mathematical shortcut.
Why does every bcrypt hash of the same password look different? Bcrypt generates a fresh random 128-bit salt for each hash operation. The salt is embedded in the output. When you verify, bcrypt extracts the salt from the stored hash and recomputes with the same salt — that’s why verification works even though the hashes look different.
Is it safe to use bcrypt in the browser? For generating test hashes and verifying known passwords: yes. For production authentication, run bcrypt server-side — browsers are untrusted environments. Never perform authentication logic in client-side code.
What’s the maximum password length for bcrypt? The bcrypt algorithm truncates inputs at 72 bytes. For most users, this is fine. If you need to support longer passwords (e.g., passphrases), pre-hash with SHA-512 before bcrypt-hashing. Some libraries (like bcrypt in newer versions) handle this automatically.
Should I use $2a$, $2b$, or $2y$?
Use $2b$ — it’s the current standard. $2a$ has a known bug with non-ASCII passwords on some implementations. $2y$ was a PHP-specific fix. $2b$ fixes all known issues and is what modern libraries produce by default.