Bcrypt exists because being fast is a defect in a password hash. A general-purpose hash such as SHA-256 is designed to run as quickly as possible, which is exactly what someone testing billions of guesses wants. Bcrypt is deliberately slow, and the cost factor sets how slow: each step up doubles the work, so a cost of 12 takes four times as long as 10 — for you once at sign-in, and for an attacker on every single guess.
A salt is generated for you and embedded in the result, which is why hashing the same password twice produces two different strings and why neither needs storing separately. The finished value carries its algorithm, its cost and its salt, so verification later needs nothing but the hash itself. The verify side compares a password against an existing hash using a constant-time comparison rather than a plain string equality.
Choosing a cost and reading the output
-
Ten is the usual floor and twelve is a reasonable target:
the right number is the highest your server can afford at your sign-in rate. Costs available here run from four, which is only useful for testing, to fourteen.
-
Only the first 72 bytes are read:
bcrypt truncates beyond that, silently, so a very long passphrase is not as strong as its length suggests. Longer input is refused here rather than quietly cut.
-
Two hashes of the same password will differ:
that is the salt doing its job. Never compare hashes to each other — compare a password against a hash, which is what the verify side does.
-
Hashing in a browser is for testing, not for production:
a real sign-in hashes on the server. Generating a hash here to seed an account or check a stored value is a fine use; sending a password to a page is not.
Being fast is the defect bcrypt was built to fix
A general-purpose hash such as SHA-256 is built to run as fast as possible, which is precisely what someone testing billions of password guesses wants from it. The [msm_tool slug="bcrypt-generator"] is deliberately slow instead, and the cost factor sets exactly how slow: each step up doubles the work required, so cost 12 takes four times as long as cost 10 — once, for a real sign-in, and on every single attempt for anyone guessing.
Choosing a cost
Ten is the usual floor and twelve a reasonable target where the server can afford it; costs from four up to fourteen are offered here, with four useful only for testing rather than anything live. The right number is the highest one a sign-in rate can absorb without becoming a problem of its own, since the same slowness that defends against guessing also costs real time on every legitimate attempt.
Only the first 72 bytes are read
Bcrypt silently truncates anything past 72 bytes of input, which means an unusually long passphrase is not actually as strong as its length suggests. Input beyond that limit is refused outright here rather than quietly accepted and hashed as something weaker than it appears to be.
Two hashes of the same password will never match
A fresh salt is generated for every run and embedded directly in the result, which is why hashing an identical password twice produces two different strings and why nothing needs to be stored separately from the hash itself. Comparing two hashes to each other is consequently the wrong operation entirely — the only valid comparison is a password against a hash, which is what the verify side actually performs, using a constant-time comparison rather than plain string equality.
A browser is for testing and seeding, not for live sign-in
Generating a hash here to seed an account manually or check a value already sitting in a database is a reasonable use. Sending a real, live password to any page as part of an actual sign-in is a different matter entirely — that hashing belongs on the server, every time, regardless of how convenient a page like this one is.
Bcrypt against the newer alternatives
Bcrypt remains sound for most applications and is supported essentially everywhere. Argon2 is the newer recommendation and holds up better against attacks that use specialised hardware, but choosing bcrypt today is not a mistake — it is a well-understood, still-current choice rather than a legacy one being phased out.