bcrypt Hash Generator and Verifier
Generate and verify bcrypt hashes locally, benchmark the cost factor on your own hardware, and see the 72-byte truncation rule that catches people out.
Runs locallyEverything happens in your browser. What you paste or drop here is never uploaded, logged or stored.
Use the tool
$2a$, which is what the underlying implementation
emits. There is no variant selector here because offering one that did not change the
output would be worse than not offering it - see below on why the distinction rarely
matters in practice.
The 72-byte limit catches everyone eventually
bcrypt reads at most 72 bytes of a password and silently discards the rest. Most implementations do not warn; they just hash the truncated value. This one refuses instead, because a hash quietly computed from the first 72 bytes of a longer password is worse than an error.
Two consequences worth knowing. A user with a long passphrase gains nothing past that point - and is never told. And because the limit is in bytes, not characters, non-ASCII hits it sooner: an emoji is four bytes, so a twenty-character password can be over the line while a seventy-character ASCII one is not.
There is a nastier version of this. Some systems pre-hash long passwords with SHA-256 and pass the hex digest to bcrypt, which is sensible - but if they pass raw binary output instead, any null byte in it truncates the password there, sometimes to nothing. If you pre-hash, use hex or base64.
Cost factor is exponential, so the numbers are misleading
The cost is a power of two: cost 12 is 4,096 rounds of key setup, cost 13 is 8,192. Raising it by one doubles the work for you and for the attacker equally. Moving from 10 to 12 makes cracking four times harder, which is a bigger step than it looks written down.
Aim for roughly 250 ms per hash on the hardware that will run it. The timing shown here is measured in your browser, which is useful for comparing costs against each other but is not your server.
Variants, and why this page does not let you pick one
- $2b$ - current. It fixed a length-handling bug that only manifests on passwords over 255 bytes, which bcrypt truncates at 72 anyway.
- $2a$ - the long-standing variant, and what this page generates.
- $2y$ - a PHP-specific marker for the fixed implementation, equivalent to $2b$ in practice.
- $2x$ - exists only to reproduce a sign-extension bug in old crypt implementations, so affected hashes can be migrated. Never generate one.
For any password under 72 bytes - which is every password bcrypt actually hashes - $2a$,
$2b$ and $2y$ produce identical output and verify interchangeably. The
implementation behind this page emits $2a$, so rather than offer a selector that
silently changed nothing but the label, there is no selector. A control that misreports what the
code did is worse than no control.
Verification reads whichever variant the hash declares, so a $2b$ or $2y$
hash from your application checks here without any of this mattering.
Is bcrypt still fine?
Yes, with a sensible cost. It has been in production since 1999, it is in every language's standard library, and it has no known breaks. Argon2id is better where you have a free hand - it is memory-hard, where bcrypt's memory use is a fixed 4 KB, which modern GPUs handle comfortably. But bcrypt at cost 12 is a perfectly defensible choice and far better than PBKDF2 with a low iteration count.
The salt is in the hash, and is not secret
A bcrypt string starts $2b$, the cost, then 22 characters of salt followed by the hash.
You store the whole thing in one column. There is no separate salt field to manage and no reason to
hide it - a salt exists to make identical passwords hash differently and to defeat precomputed
tables, and it does both jobs perfectly well in public.
Frequently asked questions
What cost should I use?
10 is the current OWASP minimum, 12 is the common production value. Measure on your own hardware: pick the highest cost whose time your login endpoint can absorb, and revisit it every couple of years as hardware improves.
Why did it refuse my long password?
Over 72 bytes. bcrypt would hash only the first 72 and discard the rest without telling you; refusing makes the limit visible rather than producing a hash that means less than it appears to.
Two systems produce different hashes for the same password.
Expected - the salt is random, so every hash differs. Verification is what tells you whether a password matches, not string comparison of two hashes.
Can I raise the cost of existing hashes?
Not directly; you need the password. The usual approach is to re-hash at the higher cost on next successful login, and keep the old hash until then.
Is anything uploaded?
No. bcrypt runs in WebAssembly inside this page, with the WASM embedded in the script, so no request is made.
References
bcrypt implementation: hash-wasm by Dani Biro, MIT licence.
Related tools
Other Tools
Popular tools from across A2Z
Rate this tool
Was this tool useful? Your feedback helps us improve it.