What is bcrypt?
bcrypt is a password hashing function designed in 1999 by Niels Provos and David Mazières. Unlike general-purpose hashes, it is intentionally slow and includes a random salt, so identical passwords produce different hashes and precomputed “rainbow tables” are useless. Its cost factor lets you make hashing slower as hardware gets faster.
Anatomy of a bcrypt hash
A bcrypt hash looks like $2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy:
$2b$— the version.$2a$,$2b$and$2y$(PHP) are compatible for normal passwords.10— the cost: 2¹⁰ = 1,024 rounds of the expensive key setup.- Next 22 characters — the 128-bit salt, Base64-encoded.
- Last 31 characters — the 184-bit hash itself.
Choosing a cost factor
Each step up doubles the time to compute one hash — for you and for an attacker. Pick the highest cost your server can afford while keeping login latency acceptable (OWASP suggests a minimum of 10):
| Cost | Iterations | Typical server time |
|---|---|---|
| 10 | 1,024 | ~50–100 ms |
| 12 | 4,096 | ~200–400 ms |
| 14 | 16,384 | ~1–1.5 s |
Browser JavaScript is slower than native code, so the progress bar above will take longer than your server would.
Important limits
- 72-byte limit. bcrypt ignores everything after the first 72 bytes of the password. Multi-byte characters (emoji, accented letters) use more than one byte each.
- Not for encryption. A hash cannot be decrypted; you can only verify a guess against it.
- Consider Argon2id for new systems — it is memory-hard and more resistant to GPU attacks — but bcrypt remains a solid, widely supported choice.
Code examples
Node.js: await bcrypt.hash(password, 12) and await bcrypt.compare(password, hash). PHP: password_hash($pw, PASSWORD_BCRYPT, ['cost' => 12]) and password_verify($pw, $hash). Python: bcrypt.hashpw(pw.encode(), bcrypt.gensalt(12)).
Uses bcrypt.js by Daniel Wirtz (Apache License 2.0).
Last updated: · Reviewed by the Password Generator team