Bcrypt Hash Generator & Verifier
Hash a password with an adjustable cost factor, or verify one against a hash you already have. Choose the $2a$, $2b$ or $2y$ version prefix and see exactly how the hash format is built β all computed locally in your browser.
Click any row to load that cost factor into the slider above. Each increment doubles the number of iterations.
How to Generate or Verify a Bcrypt Hash
Features
Why Passwords Need a Different Kind of Hash
General-purpose hash functions like MD5 and SHA-256 were built for one goal: speed. That's exactly backwards for password storage. A modern GPU can compute tens of billions of SHA-256 hashes per second, which means an attacker who steals a database of SHA-256-hashed passwords can try every common 8-character combination within minutes, not years. The 2012 LinkedIn breach exposed 117 million SHA-1-hashed passwords, and the overwhelming majority were cracked within days of the dump surfacing β not because the passwords were unusually weak, but because the hash function protecting them was never designed to resist that kind of brute-force attack in the first place.
Bcrypt exists specifically to fix this. It is deliberately, configurably slow, and that slowness is the entire security feature. Where SHA-256 hashes a password in microseconds, bcrypt at a reasonable cost factor takes on the order of a tenth of a second β utterly unnoticeable to a real user logging in once, but a massive, multiplicative obstacle to an attacker who needs to try billions of guesses against a stolen database.
Reading a Bcrypt Hash String, Piece by Piece
A bcrypt-format hash β $2b$10$N9qo8uLOickgx2ZMRZoMyeIjZAgcfl7p92ldGxad68LJZdL17lhWy β looks opaque at a glance, but every character has a defined job. The $2b$ at the start is the format version. The next field, 10, is the cost factor: the number of rounds is 2 raised to that power, so a cost of 10 means 1,024 rounds. The following 22 characters are the salt, encoded in bcrypt's own variant of Base64. Everything after that β 31 characters β is the actual hash output. All four pieces live inside that single 60-character string, which is exactly why bcrypt hashes are self-contained: nothing extra needs to be stored alongside them to verify a password later.
This tool parses that structure automatically the moment you paste a hash into Verify mode, splitting it into its four labelled components before you even enter a password to test. That makes it useful for a second, quieter purpose beyond straightforward password checking: quickly auditing what cost factor a hash in an old database or config file was actually generated with, without writing a script to do it.
The Cost Factor: Adaptive Security Against Faster Hardware
Each increment of the cost factor doubles the work required β both for your server hashing a legitimate login, and for an attacker trying to crack a stolen hash offline. Cost 10 means 1,024 iterations; cost 12 means 4,096; cost 14 means 16,384. The generally cited target, per OWASP's guidance, is to pick whatever cost factor makes a single hash take roughly a quarter of a second on your actual production hardware, then use that value going forward.
The property that makes this genuinely useful in practice β not just theoretically nice β is that bcrypt hashes are self-describing. As hardware gets faster over the years, you raise the cost factor for newly created hashes without touching the ones already sitting in your database; a hash created at cost 10 five years ago still verifies correctly today, because its own cost factor travels with it inside the string. A common production pattern is to check the embedded cost factor at every successful login and silently re-hash at the new target if the old one falls below your current minimum β no bulk migration, no forced password resets, no downtime.
Choosing a Version Prefix: $2a$ vs $2b$ vs $2y$
The version tag exists because of a real historical bug, not arbitrary versioning. The original$2a$ format shipped with an edge case in how some implementations β notably older PHP builds using crypt_blowfish β handled certain 8-bit characters in a password, occasionally producing weaker hashes than intended for specific inputs. PHP's own fix introduced $2y$, while OpenBSD's canonical fix, adopted by most other languages and libraries since, became $2b$, which is now the de facto standard almost everywhere. The version selector in this tool exists because you may need to generate a hash carrying a specific tag to match an existing system's expectations β a legacy PHP application, for instance, that specifically checks for $2y$ β even though the underlying computation is identical regardless of which tag you choose.
Who Actually Uses a Bcrypt Tool Like This
- Backend developers β sanity-checking that their auth code produces and verifies hashes correctly before wiring it into a login flow
- Developers migrating between languages or frameworks β confirming a hash generated in one stack verifies correctly against the same password checked in another
- Security engineers doing an audit β quickly reading the cost factor embedded in hashes found in an old database export or leaked credential dump
- QA engineers β generating known test hashes with a fixed password to seed a test database without touching a real signup flow
- Students learning authentication β seeing exactly how a bcrypt string is structured, and why the same password never produces the same hash twice
Real-World Scenarios
Matching a legacy PHP application's expectations. A developer inherits an older PHP codebase that stores passwords using password_hash() with an explicit $2y$check on login. Before writing a data migration script, they generate a test hash here with the$2y$ version selected, confirm it verifies correctly against the sample password, and move ahead with confidence that the format matches what the legacy code expects.
Choosing a cost factor for a new signup flow. A backend developer building a new authentication endpoint needs to decide on a cost factor before shipping. They test cost 10, 12 and 14 here against a sample password and read the actual milliseconds each one took on their own machine, then pick the highest value that still keeps login feeling instant β turning a guess into a measured decision.
Auditing an old credential export. A security engineer reviewing a legacy system's database dump finds a column of what look like password hashes. Pasting one into Verify mode immediately confirms it's bcrypt, reveals it was generated at cost 8 β below current recommendations β and flags that account population as a priority for a forced password reset and re-hash at a higher cost factor.
Bcrypt vs Argon2 vs PBKDF2 β The Honest Comparison
All three are legitimate, modern, OWASP-recommended choices, and all three leave MD5 and SHA-256 far behind for this purpose. Bcrypt has the longest production track record β in active use since 1999 β and closer-to-universal library support across languages than almost any competing scheme. It is CPU-bound, consuming computation time rather than memory. Argon2, the winner of the 2015 Password Hashing Competition, is additionally memory-hard: it requires a configurable amount of RAM during computation, which makes GPU and ASIC-based cracking considerably more expensive relative to legitimate server-side verification. PBKDF2-SHA-256 is FIPS 140-2 certified and mandated in some US government and financial-sector contexts specifically because of that certification. For most new web applications, bcrypt at cost 12 or Argon2id are the two most defensible defaults β pair whichever you choose with a strong, randomly generated password in the first place, since no hashing scheme protects a password an attacker can simply guess.
What This Tool Is β and Is Not
Read this section before relying on this tool for anything beyond learning, testing, and format inspection. It uses PBKDF2-SHA-256, run through the Web Crypto API, to produce a bcrypt-compatible hash format β the familiar $2b$ structure, a genuine 16-byte salt, a 60-character output β for demonstration and testing purposes. It is not the original Blowfish-based Eksblowfish algorithm that a real bcrypt library runs internally. Hashes generated here verify correctly against each other within this tool, but will not match output from an actual bcrypt library, and the reverse holds too.
For any production authentication system, hash passwords with a genuine server-side bcrypt implementation: bcryptjs or bcrypt for Node.js, passlib.hash.bcrypt for Python, Spring Security's BCryptPasswordEncoder for Java, PHP's password_hash() with PASSWORD_BCRYPT, or Go's golang.org/x/crypto/bcrypt. Use this tool to understand the hash format, test how cost factor affects computation time on real hardware, and check that your own implementation's output follows the structure you expect β not as the hashing layer behind a real login system.
Why Browser-Based Hashing Is Worth Trusting for Testing
A password typed into a web form that quietly phones a server before returning a result is a real trust problem, especially during development when it's tempting to test with passwords close to what you'd actually use elsewhere. Every computation here β generating a hash or verifying one β runs through the Web Crypto API entirely inside your browser tab. Disconnect from the network after the page loads and it keeps working exactly the same, which you can verify yourself in under ten seconds.
Tips for Getting This Right
- Measure, don't guess, your cost factor. Use the real timing shown after each hash to pick a cost factor that fits your server's actual response-time budget, rather than copying a number from a blog post written on different hardware.
- Default to $2b$ unless you have a specific reason not to. It's the version essentially every modern library produces and expects β only reach for $2a$ or $2y$ when matching a known legacy system.
- Re-copy a hash if Verify claims it's invalid. A bcrypt hash is always exactly 60 characters; a single dropped character from a copy-paste is the most common cause of a false "not a valid hash" warning.
- Never hash a password with plain SHA-256 or MD5 "for speed." That's precisely the mistake bcrypt exists to prevent β see the Hash Generator if you need general-purpose checksums instead of password storage.
- Test with a strong sample password, not a real one. Generate one with the Password Generator when experimenting here, and keep genuine account credentials out of any testing tool.
- Plan for cost-factor migration from day one. Check the embedded cost factor at login time and silently re-hash below-minimum accounts as users authenticate, instead of a disruptive one-time bulk migration years later.
When Bcrypt Isn't the Right Choice
Skip bcrypt if you're protecting something other than a password with a comparison-only requirement β for file integrity or checksums, use the Hash Generator's SHA-256 output instead, since bcrypt's deliberate slowness has no benefit there and only wastes CPU time. If you need to encrypt data you intend to read again later, rather than verify a secret you never store in the clear, you want AES encryption, not a one-way hash. And if your platform already offers Argon2id with adequate memory-hardness settings, it is at least as defensible a default as bcrypt for a brand-new system in 2026 β the two are closer in practice than marketing from either camp usually suggests.