Bcrypt Generator
An online bcrypt generator: make a hash, check a password against one or take a hash apart. Hashed in your browser: nothing is sent.
ForPick the libraries that will check the hash: the prefix follows.
- 10OWASP's minimum · Node, bcryptjs, Go, Spring
- 11.NET
- 12PHP 8.4, Python, Ruby, Rust
Timing bcrypt on this device…
Auto writes $2b$, OpenBSD's prefix. Pick your languages to match what they read.
Hashed in your browser: no password or hash is sent.
The hash
Your hash appears here.
Made-up examples: their text is example.
A bcrypt hash can't be decrypted: it can only be checked against a text you think it is, or guessed.
Hashed in your browser: no password or hash is sent.
No password needed: the prefix, cost and salt are stored in the hash itself.
A bcrypt hash can't be decrypted: it can only be checked against a text you think it is, or guessed.
Hashed in your browser: no password or hash is sent.

Pick your languagesThe prefix follows what every library you pick reads: PHP and Node's bcrypt share only $2a$ and $2b$.The 72-byte cutbcrypt reads the first 72 bytes. Anything past them is struck through as you type.Cost, timed hereThis device times the cost first. Each step doubles the work, and the server pays it on every check.The hash, taken apartPrefix, cost, salt and digest, each labelled.Who reads this prefix11 libraries, each with its verdict on this hash and a link to the source behind it.What is bcrypt?
bcrypt is a password hash built to be slow on purpose. It mixes the password with a random 128-bit salt through 2^cost rounds of the Blowfish key schedule, so raising the cost by one doubles the work for anyone guessing.
A bcrypt hash carries everything needed to check it: the version after $2, the cost, then 22 characters of salt and 31 of hash in bcrypt's own base64. That's why two hashes of the same password look different, and why a server needs only the stored line and the password to check it. The Decode tab is a bcrypt decoder: paste any hash to see these parts.
It was published in 1999 by Niels Provos and David Mazières, at USENIX, as "A Future-Adaptable Password Scheme": the cost lets the work grow as computers get faster.
$2b$version10$cost · 2^10 = 1,024 roundsF2BfOoKCXaWlgMjIouvrxesalt (16 bytes)0.WbSz4KRwXIPeT5AMjqGn7b1Vlf07Khash
Sources: usenix.org · man.openbsd.org
$2a$, $2b$ or $2y$: which bcrypt prefix should I use?
They're the same hash. What differs is which labels a library accepts: Node.js's bcrypt package and OpenBSD read only $2a$ and $2b$, Apache for Windows never checks $2b$, and $2a$ is read by every library below. Pick the readers above the tool and it picks the prefix.
$2a$ is the original label. $2b$ marks OpenBSD's 2014 fix for passwords of 256 characters or more, and $2y$ marks crypt_blowfish's correct implementation, which PHP writes. $2x$ is different: it means a hash made with an old bug, and libraries that accept it may not reproduce that bug.
| $2a$ | $2b$ | $2y$ | $2x$ | writes | |
|---|---|---|---|---|---|
| reads it | reads it | reads it | reads it | $2y$ | |
| reads it | reads it | doesn't read it | doesn't read it | $2b$ | |
| reads it | reads it | reads it | doesn't read it | $2b$ | |
| reads it | reads it | reads it | accepts the label only | $2b$ | |
| reads it | reads it | reads it | reads it | $2a$ | |
| reads it | reads it | reads it | doesn't read it | $2a$ | |
| reads it | reads it | reads it | reads it | $2a$ | |
| reads it | reads it | reads it | reads it | $2a$ | |
| reads it | reads it | reads it | accepts the label only | $2b$ | |
| reads it | reads it | doesn't read it | doesn't read it | $2b$ | |
| reads it | accepts the label only | reads it | reads it | $2y$ | |
| reads it | doesn't read it | reads it | reads it | $2y$ |
✓ reads it– accepts the label only✗ doesn't read it
Sources: php/php-src on GitHub · kelektiv/node.bcrypt.js on GitHub · dcodeIO/bcrypt.js on GitHub · pyca/bcrypt on GitHub · golang/crypto on GitHub · spring-projects/spring-security on GitHub · BcryptNet/bcrypt.net on GitHub · bcrypt-ruby/bcrypt-ruby on GitHub · Keats/rust-bcrypt on GitHub · openbsd/src on GitHub · apache/apr-util on GitHub · besser82/libxcrypt on GitHub · openbsd.org · openwall.com
What is a good bcrypt cost?
10 is OWASP's minimum and 12 is a common default today: PHP since 8.4, Python, Ruby and Rust all use 12. Each step doubles the time, both for an attacker and for your server on every login, so pick the highest your login can afford.
The tool times your cost on this device before it hashes, and anything from 13 up runs with an estimate and a Cancel button, so a cost of 20 can't freeze the page.
- 41/64×
- 51/32×
- 61/16×
- 71/8×
- 81/4×
- 91/2×
- 101×OWASP's minimum · Node.js bcrypt · bcryptjs · Go x/crypto · Java Spring
- 112×.NET BCrypt.Net
- 124×PHP · Python bcrypt · Ruby bcrypt · Rust bcrypt
- 138×
- 1416×
- 1532×
- 1664×
Sources: cheatsheetseries.owasp.org · php.net · php/php-src on GitHub · kelektiv/node.bcrypt.js on GitHub · dcodeIO/bcrypt.js on GitHub · pyca/bcrypt on GitHub · golang/crypto on GitHub · spring-projects/spring-security on GitHub · BcryptNet/bcrypt.net on GitHub · bcrypt-ruby/bcrypt-ruby on GitHub · Keats/rust-bcrypt on GitHub · man.openbsd.org · openbsd/src on GitHub
What is bcrypt's 72-byte limit?
bcrypt reads only the first 72 bytes of a password. Most libraries ignore the rest without a word, so two long passwords that share their first 72 bytes match each other. Some now refuse instead: Python's bcrypt since 5.0, and Go and Spring when they hash.
Bytes, not characters: in UTF-8 an accented letter takes two bytes and an emoji four, so a 30-character passphrase in another script can pass the limit. The Hash tab counts the bytes as you type and strikes out what would be ignored.
Hashing the password first with a fast hash to get round the limit has its own traps: OWASP warns about NUL bytes and "password shucking", and prescribes an HMAC with a secret pepper if you must.
Pässphrase für die Wartung: correct horse battery staple, the harbour at six in the morning
- ignores the restPHP, Node.js bcrypt, bcryptjs, .NET BCrypt.Net, Ruby bcrypt, Rust bcrypt, OpenBSD
- refuses to hash (checking still accepts)Go x/crypto, Java Spring
- refuses to hash and to checkPython bcrypt
Sources: openbsd/src on GitHub · php.net · php/php-src on GitHub · kelektiv/node.bcrypt.js on GitHub · dcodeIO/bcrypt.js on GitHub · pyca/bcrypt on GitHub · golang/crypto on GitHub · spring-projects/spring-security on GitHub · BcryptNet/bcrypt.net on GitHub · bcrypt-ruby/bcrypt-ruby on GitHub · Keats/rust-bcrypt on GitHub · man.openbsd.org · cheatsheetseries.owasp.org
How do I hash and check bcrypt in my language?
Every mainstream language has a bcrypt library with two calls: one that hashes with a fresh salt, one that checks a password against a stored hash. Never compare hashes as strings: the salt makes each hash different.
$hash = password_hash($password, PASSWORD_BCRYPT, ['cost' => 12]); $ok = password_verify($password, $hash);
const hash = await bcrypt.hash(password, 12); const ok = await bcrypt.compare(password, hash);
hashed = bcrypt.hashpw(password.encode(), bcrypt.gensalt(rounds=12)) ok = bcrypt.checkpw(password.encode(), hashed)
hash, err := bcrypt.GenerateFromPassword([]byte(password), 12) err = bcrypt.CompareHashAndPassword(hash, []byte(password)) // nil = match
var encoder = new BCryptPasswordEncoder(12); String hash = encoder.encode(password); boolean ok = encoder.matches(password, hash);
string hash = BCrypt.Net.BCrypt.HashPassword(password, 12); bool ok = BCrypt.Net.BCrypt.Verify(password, hash);
hash = BCrypt::Password.create(password) # cost 12 by default ok = BCrypt::Password.new(hash) == password
let hash = bcrypt::hash(password, 12)?; let ok = bcrypt::verify(password, &hash)?;
Sources: php.net · kelektiv/node.bcrypt.js on GitHub · pyca/bcrypt on GitHub · golang/crypto on GitHub · docs.spring.io · BcryptNet/bcrypt.net on GitHub · bcrypt-ruby/bcrypt-ruby on GitHub · Keats/rust-bcrypt on GitHub
Argon2 vs bcrypt: which should I use?
For a new system, OWASP recommends Argon2id first, then scrypt, with bcrypt for legacy systems at a cost of 10 or more and PBKDF2 where FIPS-140 compliance is required. Argon2 won the Password Hashing Competition in 2015. bcrypt is still sound where it already runs, within its 72-byte limit.
- Argon2idfirst choice
- scryptwhere Argon2id isn't available
- bcryptlegacy systems, cost 10 or more, 72-byte limit
- PBKDF2where FIPS-140 compliance is required
Sources: cheatsheetseries.owasp.org · password-hashing.net · OWASP/CheatSheetSeries on GitHub
Can bcrypt be decrypted?
No. There's no bcrypt decrypt: bcrypt is one-way, so there's nothing to decrypt. Someone holding the hash can only guess passwords and run bcrypt on each guess, which is what the cost slows down. The Check tab answers the question that's left: does this password match this hash?
One graphics card manages about 305,000 bcrypt guesses a second at cost 5, and every step up halves that: about 9,500 at cost 10 and 600 at cost 14.
- bcrypt, cost 5304,800 guesses a second
- bcrypt, cost 109,525 guesses a second
- bcrypt, cost 122,381 guesses a second
- bcrypt, cost 14595 guesses a second
Sources: gist.github.com · openbsd/src on GitHub
bcrypt FAQ
Is it safe to make a bcrypt hash online here?
What is a good bcrypt cost?
Why does my $2y$ hash fail in Node.js?
$2a$ and $2b$ hashes, so compare() returns false for the $2y$ hashes that PHP and htpasswd write, even with the right password. The hash itself is the same under all three prefixes, so changing $2y$ to $2b$ makes it match. bcryptjs, the pure JavaScript package, reads $2y$ as it is.$2a$ vs $2b$ vs $2y$: what's the difference?
$2a$ is the original prefix; OpenBSD added $2b$ in 2014 to fix a length bug in its own code, and crypt_blowfish writes $2y$ for correctly computed hashes, which behave exactly like $2b$. What differs is who accepts which: OpenBSD and Node's bcrypt refuse $2y$, Apache for Windows refuses $2b$, and all of them read $2a$.Why are two hashes of the same password different?
What is bcrypt's 72-byte limit?
Can bcrypt be decrypted?
Should I use Argon2 instead of bcrypt?
Missing something?Suggest a feature or a new tool
Related tools
Htpasswd Generator
Create .htpasswd users with bcrypt, APR1 or SHA-512, check a password against a line, and get the config for Apache, nginx, Caddy and more; hashed in your browser
Password Generator
Strong random passwords, passphrases and PINs made in your browser, each with its exact bits and crack time
Password Strength Tester
How long a password takes to crack by 8 named attacks, the patterns that weaken it, and a private breach check
UUID Generator
Generate UUID v4, v7, v1, v5 and v3 or GUIDs in bulk, in any format, and decode a UUID's version and timestamp