Free tool
Bcrypt generator and checker
Type a password to get its bcrypt hash at the cost you choose, with the time it took. Paste an existing hash to check a password against it and see its version, cost and salt.
Free · no sign-up · runs in your browser, nothing is uploaded
0 / 72 bytes
The hash appears here as you type.
Paste a hash from your database or a config file to see whether a password matches it.
How bcrypt works
bcrypt was published by Niels Provos and David Mazières in 1999. It is built on the Blowfish cipher, with a deliberately expensive key setup that runs 2cost times. That makes each hash slow to compute, and the cost can be raised as hardware gets faster without changing the algorithm.
The output is one self-describing string, so the salt and cost are stored with the hash and need no separate column:
$2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy $2b$ prefix 10$ cost N9qo8uLOickgx2ZMRZoMye salt (22 characters) IjZAgcfl7p92ldGxad68LJZdL17lhWy hash (31 characters)
| Part | Length | Meaning |
|---|---|---|
| $2b$ | 4 | Algorithm revision: $2a$, $2b$ or $2y$ |
| 10$ | 3 | Cost: log2 of the key setup rounds (04 to 31) |
| salt | 22 | 128 random bits, in bcrypt's own Base64 alphabet (./A-Za-z0-9) |
| hash | 31 | The first 23 bytes of the encrypted result |
To check a login, the server reads the prefix, cost and salt from the stored string, hashes the typed password with them and compares the two results. That is what the checker above does.
Choosing a bcrypt cost factor
The cost is the one setting that matters. Each step doubles the time per hash, for you and for anyone trying to guess passwords from a leaked database. OWASP asks for a cost of at least 10. Above that, measure on your production hardware and pick the highest cost that keeps login fast enough under your peak load.
| Cost | Rounds (2^cost) | Relative time |
|---|---|---|
| 10 | 1,024 | 1x |
| 11 | 2,048 | 2x |
| 12 | 4,096 | 4x |
| 13 | 8,192 | 8x |
| 14 | 16,384 | 16x |
The tool times the hash it just made and estimates every other cost from it, so you can see the doubling on your own machine. It runs bcryptjs in JavaScript, which its authors put at about 30% slower than the native binding, so a server running native bcrypt is usually somewhat faster.
Raising the cost later is easy: after a successful login, check the cost in the stored hash (for example bcrypt.getRounds(hash) in Node or password_needs_rehash() in PHP) and store a new hash if it is below your current setting.
The 72-byte limit and other gotchas
Only the first 72 bytes count. bcrypt silently ignores the rest of a longer password. With UTF-8, accented letters take 2 bytes and emoji 4, so the limit is often lower than 72 characters. If you must accept longer passphrases, do not pre-hash with a raw binary digest: bcrypt stops at a zero byte in many implementations. Prefer an algorithm without the limit, such as Argon2id.
Prefixes. Hashes made by PHP and Apache start with $2y$; Node, Python and Go libraries write $2b$ or $2a$. They verify each other for normal passwords. If a library rejects a prefix, changing $2y$ to $2b$ in the string is a known workaround, since the algorithm is the same. A $2x$ hash came from the old crypt_blowfish bug and should be replaced at the next login.
Do not compare hashes as strings. Two hashes of the same password differ because of the salt. Always call the library's compare or verify function.
bcrypt in Node.js, Python, PHP and Go
// Node.js: npm i bcrypt (native) or bcryptjs (pure JS, same API) import bcrypt from 'bcrypt'; const hash = await bcrypt.hash(password, 12); const ok = await bcrypt.compare(password, hash);
# Python: pip install bcrypt import bcrypt hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)) bcrypt.checkpw(password.encode(), hashed)
<?php $hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); // $2y$12$... password_verify($password, $hash);
// Go: golang.org/x/crypto/bcrypt hash, err := bcrypt.GenerateFromPassword([]byte(password), 12) err = bcrypt.CompareHashAndPassword(hash, []byte(password)) // nil means match
# Shell, with Apache's htpasswd (prints only the hash) htpasswd -bnBC 12 "" 'the password' | tr -d ':\n'
bcrypt vs Argon2, scrypt and PBKDF2
| Algorithm | OWASP guidance | Notes |
|---|---|---|
| Argon2id | First choice | Memory-hard, so GPU cracking is expensive; no 72-byte limit |
| scrypt | When Argon2id is not available | Memory-hard; tune N, r and p |
| bcrypt | For legacy systems, cost 10 or more | Built into most frameworks; 72-byte input limit |
| PBKDF2 | When FIPS-140 compliance is required | Needs a very high iteration count |
Fast hashes such as MD5 and SHA-256 are the wrong tool for passwords even with a salt. They are right for checksums and signatures: use the hash generator for those. To protect a folder or a staging site with a password, the htpasswd generator writes bcrypt lines for Apache and Nginx. More security tools are in security tools on DevHunt.
More free developer tools
Looking for a full product instead? See security tools on DevHunt.
FAQ
Can a bcrypt hash be decrypted?+
No. bcrypt is a one-way function: the hash cannot be turned back into the password. The only way to find the password is to guess it and hash each guess with the same salt and cost, which bcrypt makes slow on purpose. Strong, unique passwords stay out of reach.
Why does the same password give a different bcrypt hash each time?+
Every hash gets a new random 128-bit salt, and the salt is stored inside the hash string (the 22 characters after the cost). Verification reads the salt and cost back out of the stored hash, hashes the password again with them, and compares. So different-looking hashes of one password all verify.
What bcrypt cost factor should I use?+
OWASP says at least 10. Each step doubles the work, so pick the highest cost your login server can afford, measured on that server: many teams aim for roughly a quarter to half a second per hash. The table under the tool estimates every cost from one measured hash in your browser.
What is the maximum password length for bcrypt?+
72 bytes. bcrypt ignores everything after that, so two long passwords that share the first 72 bytes produce the same hash. UTF-8 characters can take up to 4 bytes, so the limit can be as low as 18 emoji. The tool counts bytes as you type and warns past 72.
What is the difference between $2a$, $2b$ and $2y$?+
They are revisions of the same algorithm. $2a$ is the original prefix. $2y$ marks hashes from the fixed crypt_blowfish (used by PHP and Apache) after a 2011 bug with non-ASCII characters, which produced $2x$ hashes. $2b$ is OpenBSD's 2014 revision after a bug with passwords over 255 bytes. For normal passwords all three give the same hash and most libraries verify all of them.
How long is a bcrypt hash, and how should I store it?+
Always 60 characters: $2b$ (4), the cost and a $ (3), a 22-character salt and a 31-character hash. A CHAR(60) or VARCHAR(60) column fits it; many teams use VARCHAR(255) so the column can hold a longer algorithm such as Argon2 later.
Is bcrypt still a good choice?+
Yes, with a cost of 10 or more. OWASP lists Argon2id first for new systems, then scrypt, and recommends bcrypt where those are not available. bcrypt is built into most web frameworks, which is why it is still the most common password hash.
Is it safe to type a real password here?+
Hashing runs in a web worker in your browser with the bcryptjs library. The password is not sent anywhere and never goes into the URL. Even so, for a production password the safest place to hash it is your own server or a terminal.
Sources: OWASP Password Storage Cheat Sheet · Provos & Mazières, A Future-Adaptable Password Scheme (1999) · bcryptjs README · Openwall crypt_blowfish ($2x$/$2y$) · OpenBSD bcrypt(3) · PHP password_hash() · Python bcrypt · Go x/crypto/bcrypt. Checked 2026-10-30.