Security
Free Bcrypt Password Hash Generator
Generate bcrypt hashes from passwords and verify them. Adjustable cost factor.
What is bcrypt — and why not just use SHA-256?
Bcrypt is a password hashing function designed by Niels Provos and David Mazières in 1999, based on the Blowfish block cipher. Unlike general-purpose hash functions like SHA-256, bcrypt was purpose-built for one job: making password verification deliberately slow.
The core problem with using SHA-256 for passwords is speed. A modern GPU can compute over 10 billion SHA-256 hashes per second. That means an attacker who steals a database of SHA-256 hashed passwords can try every possible 8-character password in under an hour. Bcrypt solves this by being orders of magnitude slower — at cost factor 12, a single bcrypt hash takes roughly 300 milliseconds, limiting an attacker to just 3–4 attempts per second per CPU core.
Bcrypt also includes a built-in salt — a random 128-bit value generated for each password. The salt is stored as part of the hash output, so no separate salt column is needed in your database. Salting ensures that two users with the same password get different hashes, defeating precomputed rainbow table attacks. For a deeper comparison of password hashing algorithms, see our guide on bcrypt vs Argon2 vs scrypt.
Anatomy of a bcrypt hash string
Every bcrypt hash is exactly 60 characters long and follows a fixed format. Understanding this format helps when debugging authentication issues or migrating between systems:
$2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy ├──┤├┤├────────────────────┤├─────────────────────────────┤ │ │ │ │ │ │ │ Hash (31 chars) │ │ Salt (22 chars, Base64) │ Cost factor (2^10 = 1024 rounds) Algorithm identifier (2a)
Algorithm identifiers
The prefix $2a$ is the most common. Other variants include $2b$ (fixed a wrapping bug in the OpenBSD implementation) and $2y$ (PHP-specific fix for an early crypt_blowfish bug). In practice, all three are interchangeable for modern implementations — the output of $2a$, $2b$, and $2y$ is identical for valid UTF-8 passwords under 72 bytes.
The 72-byte password limit
Bcrypt truncates passwords to 72 bytes before hashing. For ASCII passwords (1 byte per character), this means 72 characters. For UTF-8 passwords with multi-byte characters (accented letters, emoji), the effective limit is lower. Passwords beyond this limit are silently truncated — characters after byte 72 are ignored. This is rarely a practical issue (few users choose 72+ character passwords), but if it matters, a common workaround is to pre-hash the password with SHA-256 before passing it to bcrypt: bcrypt(sha256(password)).
Choosing the right cost factor
The cost factor is the single most important parameter in bcrypt. It determines the computational cost of hashing and should be tuned to your hardware and latency budget:
| Cost | Rounds | Approx. time* | Recommendation |
|---|---|---|---|
| 4 | 16 | ~1 ms | Testing/development only |
| 8 | 256 | ~10 ms | Acceptable for low-sensitivity systems |
| 10 | 1,024 | ~100 ms | OWASP minimum — good default |
| 11 | 2,048 | ~200 ms | Recommended for most production apps |
| 12 | 4,096 | ~300 ms | Strong — used by Dropbox, many Rails apps |
| 13 | 8,192 | ~600 ms | Very strong — noticeable login delay |
| 14 | 16,384 | ~1.2 s | High security — may affect UX on login |
* Approximate times on a 2023 x86-64 server CPU (single core). Browser JavaScript is 3–5× slower. GPU times are similar — bcrypt is CPU-hard but not memory-hard, so GPUs offer modest speedup compared to SHA-256.
The ideal approach: benchmark on your production hardware and pick the highest cost that keeps hash time under 250–500 ms. As hardware gets faster, increase the cost. You can do this transparently by rehashing each password with the new cost on the user's next successful login — bcrypt stores the cost in the hash itself, so old and new cost hashes coexist in the same database column.
Bcrypt vs Argon2 vs scrypt — which should you use?
| Algorithm | Year | Hardness | OWASP status | Best for |
|---|---|---|---|---|
| bcrypt | 1999 | CPU-hard | Recommended | Most web apps, especially if framework provides it natively |
| scrypt | 2009 | CPU + memory-hard | Recommended | Systems needing GPU resistance without Argon2 support |
| Argon2id | 2015 | CPU + memory + GPU-hard | Primary recommendation | New projects with library support (Go, Rust, Python, Node) |
For existing codebases using bcrypt: there is no urgent reason to migrate. Bcrypt at cost 12+ remains secure and is not cryptographically broken. Migration to Argon2id is a future-proofing decision, not a security emergency. If you do migrate, use the "rehash on login" strategy — check if the stored hash is bcrypt, and if so, rehash with Argon2id on successful authentication.
Common bcrypt mistakes to avoid
Using bcrypt in popular languages
const bcrypt = require('bcryptjs');
const hash = await bcrypt.hash(password, 12);
const match = await bcrypt.compare(password, hash);import bcrypt hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)) match = bcrypt.checkpw(password.encode(), hashed)
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); $match = password_verify($password, $hash);
require 'bcrypt' hash = BCrypt::Password.create(password, cost: 12) match = BCrypt::Password.new(hash) == password
hash, _ := bcrypt.GenerateFromPassword([]byte(password), 12) err := bcrypt.CompareHashAndPassword(hash, []byte(password))
FAQ
Common questions
What is bcrypt and why is it used for passwords?
Bcrypt is a password hashing function based on the Blowfish cipher, designed in 1999 by Niels Provos and David Mazières. Unlike fast hash functions like SHA-256 (which can compute billions of hashes per second), bcrypt is intentionally slow — making brute-force attacks impractical. It also incorporates a random salt automatically, preventing rainbow table attacks. Bcrypt remains one of the most widely recommended password hashing algorithms.
What does the cost factor mean?
The cost factor (also called work factor or log rounds) determines how many iterations bcrypt performs internally. The number of rounds is 2^cost — so cost 10 means 1,024 rounds, cost 12 means 4,096 rounds, and cost 14 means 16,384 rounds. Higher cost = slower hashing = harder to brute-force. OWASP recommends a minimum cost of 10 for production systems, with 12 being a common choice in 2024–2025.
What cost factor should I use in production?
Choose the highest cost that keeps hashing time under your acceptable threshold — typically 250–500 ms per hash for login endpoints. On modern hardware, cost 10 takes ~100 ms, cost 12 takes ~300 ms, and cost 14 takes ~1–2 seconds. Start at 10 and benchmark on your production hardware. You can increase the cost over time as hardware gets faster — just rehash passwords on next successful login.
What do the parts of a bcrypt hash mean?
A bcrypt hash like $2a$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy has four parts separated by $: the algorithm identifier (2a), the cost factor (10), a 22-character Base64-encoded salt (N9qo8uLOickgx2ZMRZoMye), and the 31-character Base64-encoded hash output (IjZAgcfl7p92ldGxad68LJZdL17lhWy). The total is always exactly 60 characters.
Is bcrypt still secure in 2025?
Yes, bcrypt remains a secure and OWASP-recommended choice for password hashing. However, for new projects, OWASP now recommends Argon2id as the primary choice because it offers better resistance to GPU-based attacks and side-channel attacks. Bcrypt is still the standard in many frameworks (Rails, Django, Laravel, Spring Security) and is perfectly acceptable — there is no urgent need to migrate existing systems from bcrypt to Argon2id.
What is the difference between bcrypt, scrypt, and Argon2?
All three are slow password hashing algorithms designed to resist brute-force attacks. Bcrypt (1999) is CPU-hard — it resists CPU-based attacks but is vulnerable to GPU parallelism. Scrypt (2009) adds memory-hardness, making GPU attacks more expensive. Argon2id (2015, winner of the Password Hashing Competition) is both CPU-hard and memory-hard with tunable parallelism, and is currently the OWASP top recommendation for new projects.
Is my password safe when using this tool?
Yes. All hashing and verification runs locally in your browser using JavaScript. Your password is never sent to any server, never stored, and never logged. You can verify this by disconnecting from the internet and using the tool offline — it will work identically.
Why does the same password produce a different hash each time?
Because bcrypt generates a random 128-bit salt for each hash operation. The salt is embedded in the output hash string, so verification still works — bcrypt extracts the salt from the stored hash and uses it to re-hash the input password for comparison. This means even identical passwords stored for different users produce completely different hash strings, preventing attackers from spotting duplicate passwords.
More in Security