◇ Security & Cryptography

Bcrypt Hash Generator & Verifier

Hash a password with bcrypt at cost 4–15, verify a password against a $2a$/$2b$/$2y$ hash, and inspect a hash's version, cost and salt. Runs in a worker; nothing is stored.

Cost 4–15, cancelable $2a$ / $2b$ / $2y$ 72-byte limit warning Never stored or shared

Loading Bcrypt…

What this page sends

  • Your input: Passwords are hashed in a Web Worker in this tab. They are not saved, not put in a link and not sent to a server.
  • Page load: Loading the page requests HTML, scripts and images from ByteKiln, fonts from Google Fonts, and sends Google Analytics page views, tool-usage events and catalog interactions (tool/category IDs, result status and whether a click followed search — never your input, output or search terms). Privacy & sharing

How the Bcrypt Hash Generator & Verifier Works

bcrypt is the password hash behind a large share of the web — Laravel, Rails' has_secure_password, Spring Security's BCryptPasswordEncoder, Django's optional hasher, and countless Node apps. When a login stops working after a migration, or you need a hash to seed a test user, you want to check a password against a hash without writing a script. This tool does three things. Generate hashes a password at a cost factor from 4 to 15 in a background Web Worker, showing how long it took and letting you cancel slow high-cost runs. Verify checks a password against any $2a$, $2b$ or $2y$ hash. Inspect splits a hash into its version, cost, salt and hash parts, with a specific error when a hash is truncated (a database column shorter than 60 characters is a classic cause), has the wrong prefix, or is actually a different algorithm such as SHA-512-crypt or Argon2. It warns when a password is longer than bcrypt's 72-byte limit. Output is tested against pyca/bcrypt on the OpenBSD test vectors.

Hash anatomy

$2b$10$ then 53 characters: 22 characters of salt (16 bytes in bcrypt's own Base64 alphabet, ./A–Za–z0–9) and 31 characters of hash (23 bytes). The cost is log2 of the number of key-setup rounds: 10 means 1,024 rounds.

Implementation

Hashing uses bcryptjs, a pure-JavaScript bcrypt, running in a Web Worker so the page stays responsive. Verification uses a constant-time comparison. $2y$ and $2b$ hashes are handled as the same algorithm; generated hashes use $2b$.

Privacy

The password is kept only in the page's memory while you use it. It is not saved in local storage, not included in any link, and not sent to analytics.

Testing

The unit tests reproduce the classic OpenBSD / jBCrypt vectors and additional cases (Unicode, the 72-byte boundary, $2y$) generated with pyca/bcrypt, an independent implementation, and round-trip random passwords.

Limitations

  • bcryptjs is pure JavaScript, several times slower than native bcrypt: a cost of 12 takes a noticeable moment and 15 can take several seconds or more on a slow device.
  • bcrypt uses only the first 72 bytes of a password; the tool warns but can't change the algorithm.
  • Argon2, scrypt and PBKDF2 are not supported.
  • Hashes made here are for tests and learning. Production hashing belongs on your server with your framework's password hasher.

FAQ

Short answers for the things developers usually ask before trusting a tool.

Is my password uploaded?

No. Hashing and verification run in a Web Worker in your browser. Passwords and hashes are never stored, logged, or put in a share link. Even so, this tool is for testing and learning — in production, hash passwords on your server with your framework's password hasher.

What cost factor should I use?

Pick the highest cost your server can afford per login — commonly 10–12 today, aiming for roughly 100–300 ms per hash on your hardware. Each +1 doubles the time. OWASP currently recommends at least 10. Browsers are slower than servers, so costs of 13+ can take several seconds here; you can cancel.

What is the difference between $2a$, $2b$ and $2y$?

They are the same algorithm with different histories. $2a$ is the long-standing format; $2b$ was introduced by OpenBSD in 2014 to fix a bug with passwords longer than 255 bytes; $2y$ is PHP's marker for its fixed implementation. For normal passwords all three produce the same hash, and this tool verifies all of them. ($2x$ marks hashes from an old buggy PHP implementation and may not verify for non-ASCII passwords.)

Why does bcrypt ignore part of my long password?

bcrypt only uses the first 72 bytes of the password — bytes of UTF-8, not characters, so a password of 36 characters like "é" already reaches it. Anything after byte 72 is ignored. The tool warns when you go over. If you need longer inputs, pre-hash with SHA-256 (carefully, Base64-encoded to avoid NUL bytes) or use Argon2id.

Why does every hash of the same password look different?

Each hash includes a random 16-byte salt (the 22 characters after the cost). The salt is stored in the hash, so verification reads it back and recomputes. Two users with the same password get different hashes, which defeats precomputed rainbow tables.

Is bcrypt still a good choice?

Yes for most applications, and it's the default in many frameworks. Argon2id is the current OWASP first choice because it is also memory-hard, which slows GPU cracking more. If you already use bcrypt with a reasonable cost, there is no urgency to migrate.

Related tools

Useful follow-ups when one conversion usually turns into three more.