ToolJutsu
All tools
Developer Tools

bcrypt Generator

Hash and verify passwords with bcrypt at a configurable cost factor.

Processed on your device. We never see your files.

How to use bcrypt Generator

What is bcrypt?

bcrypt is a password-hashing function published by Niels Provos and David Mazières in 1999, originally for OpenBSD. It is not a general hash like SHA-256 — it is a key-derivation function designed explicitly for storing passwords. Two design choices make it appropriate for passwords:

  • A built-in salt. Every hash uses a fresh 16-byte random salt, embedded in the output string. Two users with the same password get different hashes, defeating precomputed-table (rainbow-table) attacks.
  • A tunable cost factor. The function is deliberately slow, and how slow is configurable. As CPUs get faster you raise the cost. The whole point is to make brute-force guessing expensive.

bcrypt has been a default in Ruby on Rails, Django, Spring Security, Laravel and dozens of other frameworks for over two decades. It remains a perfectly defensible choice today, even though argon2id is the newer hot pick.

How bcrypt works

The output looks like this:

$2b$12$R9h/cIPz0gi.URNNX3kh2OPST9/PgBkqquzi.Ss7KIUgO2t0jWMUW

Breaking that apart:

  • $2b$ — algorithm identifier and version. $2a$, $2b$ and $2y$ are all bcrypt; the differences are bug-fix revisions in the C reference implementation. Modern libraries emit $2b$ and accept the others on read.
  • 12 — the cost factor. 2¹² = 4,096 rounds of the Eksblowfish key schedule. Each increment doubles the work.
  • R9h/cIPz0gi.URNNX3kh2O — the 22-character base64 encoding of the 16-byte random salt.
  • PST9/PgBkqquzi.Ss7KIUgO2t0jWMUW — the 31-character base64 encoding of the 24-byte hash output.

To hash, the library generates a fresh salt, runs the Eksblowfish key-schedule against the password and salt 2^cost times, encrypts a fixed 24-byte string ("OrpheanBeholderScryDoubt") with the resulting Blowfish state, and emits the formatted string above. To verify, it parses the cost and salt from the stored hash, repeats the same computation against the candidate password, and compares the result in constant time. There is no separate salt parameter because the salt rides along inside the hash.

Common use cases

  • User password storage in a relational or document database. Hash on signup, verify on login, re-hash on login if the stored cost is below your current target (transparent upgrades).
  • API key fingerprinting where the secret is human-typeable — same threat model as passwords.
  • Legacy migration. Importing user records from a system that stored MD5 or plain SHA-256 hashes — bcrypt-of-old-hash gives you a defensible interim posture while you force resets on next login.
  • Local development and tests. Generating fixture hashes for integration tests without paying the per-run hashing cost — pick cost 4 for tests, never for production.

How to use this bcrypt generator

  1. Choose a mode: Hash to produce a new hash from a password, or Verify to check a password against an existing hash.
  2. In Hash mode, type the password, pick a cost factor (4–15), and click Generate. The output is the full $2b$cost$saltHash string ready to store in a database column.
  3. In Verify mode, paste both the password and a stored hash and click Verify. The tool returns match or no match. The cost and salt are parsed from the hash automatically.
  4. Use the Copy button to grab the result. Hashes are deterministic given the salt; new salts come from crypto.getRandomValues each generation.

Security considerations

  • Cost factor matters. Cost 4 hashes in milliseconds and is brute-forceable; cost 10 is the conservative floor; cost 12 is the current recommendation; cost 14+ is heavy on a typical web server. Calibrate to ~250 ms per hash on your production CPU.
  • 72-byte truncation. bcrypt only consumes the first 72 bytes of input. Long passphrases lose entropy silently. Pre-hash with SHA-256 if you need to support long inputs, or use argon2id.
  • Don’t double-hash badly. bcrypt(md5(password)) is a real pattern from legacy migrations and is fine as a transitional measure, but it does not compose strength — the MD5 step caps the input entropy. Migrate to direct bcrypt-of-password on next successful login.
  • Constant-time compare. Always use the library’s compare function. String equality (===) is timing-side-channel leaky.
  • Re-hash on cost upgrade. When you raise your application’s cost target, re-hash on successful login (you already have the plaintext in scope) rather than forcing a global reset.

Privacy

The password and the resulting hash exist only in this browser tab. The bcryptjs library is lazy-loaded on first use, runs entirely on your CPU via crypto.getRandomValues for the salt, and never makes a network request afterwards. Turning off Wi-Fi after the page loads does not interrupt the tool. There is no analytics on the values you enter.

Compatibility notes

Hashes produced here are bit-for-bit interoperable with every mainstream bcrypt library: bcrypt (Node.js native), bcryptjs (pure JavaScript), python-bcrypt, passlib, Ruby’s bcrypt-ruby, Go’s golang.org/x/crypto/bcrypt, Spring Security, PHP’s password_hash($pw, PASSWORD_BCRYPT). The $2a$ / $2b$ / $2y$ prefix variants are all accepted across libraries; this tool emits $2b$. Verification accepts all three.

Frequently asked questions

Which cost factor should I pick?
The cost factor is a power of two: a cost of 10 means 2¹⁰ = 1,024 key-stretching rounds, cost 12 means 4,096, cost 14 means 16,384. Each increment doubles the work. The right pick depends on how fast your server is and how slow you can afford a login to be. A useful calibration: pick the highest cost that completes in roughly 250 ms on your production hardware. On a modern x86 server that is typically cost 12; on a budget VPS, cost 10 or 11. The bcrypt creators (Provos and Mazières, 1999) explicitly designed the cost factor to let you re-tune over decades as hardware speeds up — and they expected you to. Cost 10 is a safe default, cost 12 is the current recommendation for new applications, and anything below 10 should only be used for tests.
How do I verify a password against a stored hash?
Switch the tool to Verify mode, paste the candidate password and the stored hash. The hash itself encodes everything bcrypt needs: the algorithm version ($2a$, $2b$, $2y$), the cost factor, the 22-character base64 salt and the 31-character base64 hash. Bcrypt re-computes the hash of the candidate password using the embedded salt and cost, and compares it in constant time. There is no separate salt argument — that is one of the conveniences of the bcrypt format. On the server side, this is bcrypt.compare(password, hash) in any standard library.
Why does bcrypt silently truncate passwords at 72 bytes?
It is a quirk of the original Blowfish-based design: the key schedule mixes in at most 72 bytes of password material. Most libraries silently truncate longer inputs, which means a 200-character password is no stronger than its first 72 bytes. If you expect long passphrases or want to support emoji-heavy passwords (where one user-visible character can be 4+ UTF-8 bytes), pre-hash with SHA-256 and base64-encode the result before passing it to bcrypt — or migrate to argon2id, which has no such limit.
Should I use bcrypt, argon2 or scrypt for new applications?
Argon2id is the modern winner (PHC competition, 2015) and is what OWASP recommends for greenfield projects — it is memory-hard, which raises the cost of GPU and ASIC attacks more steeply than bcrypt does. scrypt is also memory-hard and a fine choice. bcrypt is still secure, well-studied and present in every framework on earth; it just isn't memory-hard, so a determined attacker with custom hardware can crack bcrypt cheaper per dollar than argon2id. If you already use bcrypt, you do not need to migrate urgently — but for new code, argon2id is the default to reach for.
Is anything sent to a server?
No. The hashing runs entirely in your browser via bcryptjs, lazy-loaded the first time you click Generate. Your password is never transmitted, logged or stored. You can verify in the browser's Network tab: after the initial bundle and the lazy bcryptjs chunk load, there are no further requests.

Related tools