Overview
Produces bcrypt-format strings - a $2a$ prefix, a cost factor from 4 to 16, a 22-character salt and a 31-character digest in bcrypt's base64 alphabet - entirely in the browser. One honest note up front: the derivation inside is PBKDF2-SHA-256, not the real bcrypt algorithm, so the output mimics the modular crypt format rather than being interoperable with bcrypt libraries.
How It Works
Type a password, drag the cost slider between 4 and 16, and press Hash Password. The output is a $2a$-prefixed string in the familiar layout, and it is preloaded into the verifier panel on the right. The verifier accepts a hash in $2a$, $2b$ or $2y$ form plus a password, and reports match or no-match. Nothing is sent anywhere, and each hash uses a fresh random salt.
Step-by-Step Usage Guide
- Enter the password you want the demo hash for. Remember this is format demonstration, not production hashing.
- Set the cost factor with the slider. Each step doubles the internal iteration count; watch how the work scales as you move it.
- Press Hash Password and inspect the assembled string: prefix, two-digit cost, 22-character salt, 31-character digest.
- Use the verifier panel to see the prefix check in action with $2a$, $2b$ and $2y$ inputs.
Technical Specifications & Standards
Precision matters here. Real bcrypt (Provos and Mazieres, 1999) runs a modified Blowfish key schedule 2^cost times. This tool instead derives 192 bits with PBKDF2-HMAC-SHA-256, using a 16-byte random salt and 2^cost times 10 iterations (capped at cost 14), then renders the salt and digest with bcrypt's base64 alphabet - './' plus alphanumerics - into the classic $2a$NN$ 22+31 character layout. The result is format-compatible-looking but algorithm-incompatible: a real bcrypt implementation such as bcrypt.js or PHP's password_verify will reject these strings, and hashes from those libraries cannot be verified here. The verifier's check is similarly shallow - it confirms the string starts with a bcrypt prefix and a password was entered, rather than recomputing and comparing digests. What the tool is genuinely good for is seeing the modular crypt format assembled, generating realistic fixtures for UI work, and demonstrating why cost factors exist; what it is not for is storing real passwords. For that, use a vetted bcrypt or Argon2id library, with a work factor of at least 10 for bcrypt per OWASP's Password Storage Cheat Sheet.
Targeted Use Cases
- Creating realistic bcrypt-shaped strings for mockups, seed data and schema documentation without a bcrypt dependency.
- Teaching the modular crypt format: prefix, cost, salt and digest, and why the salt is embedded in the hash string itself.
- Checking that a password field or regex in your app accepts and displays $2a$-style strings correctly.
- Demonstrating why a verifier must re-derive with the embedded salt and cost rather than doing a string comparison.
Notes & Gotchas
- Do not store these strings as real password hashes. They will not verify with actual bcrypt implementations, which is a data-loss bug waiting to happen.
- For real systems use a vetted library implementing genuine bcrypt or Argon2id, with a minimum work factor of 10 for bcrypt per OWASP guidance.
- Treat the verifier as a format checker, not a password check - it does not recompute the digest against the password.
- Keep real credentials out of browser text fields; use dummy values here and reserve actual passwords for your own infrastructure.
Frequently Asked Questions
Is this real bcrypt?
No, and the distinction matters. The string layout follows the bcrypt modular crypt format, but the digest is derived with PBKDF2-HMAC-SHA-256 rather than bcrypt's Blowfish-based key schedule. Real bcrypt libraries will not verify these strings, and this tool will not verify their hashes beyond the prefix.
What do $2a$, $2b$ and $2y$ mean?
They are bcrypt revision identifiers that emerged from implementation history: 2a was the original widely deployed variant, 2b fixed a wraparound bug, and 2y is an OpenBSD correction marker. Most libraries treat all three as the same algorithm today, which is why the verifier accepts all three prefixes.
Why is my hash different every time for the same password?
A fresh 16-byte random salt is generated for each run, and the salt is embedded in the output string. Real bcrypt behaves the same way - a unique salt per hash is a core property, not a bug.
Can I use this to verify a hash from my database?
Not meaningfully. The verifier checks that the string carries a bcrypt prefix and that you typed a password; it does not recompute the digest. To verify a real bcrypt hash, use a bcrypt library in your application or a dedicated verifier tool.