Password Strength and Breach Check
Local entropy estimate plus optional HIBP k-anonymity breach check. Your password never leaves the browser.
Privacy: The password itself never leaves your browser. Strength scoring and generation are local, and the password is deliberately never written to the URL, so the shareable link cannot leak it. The breach check is the only network call: your browser computes the SHA-1 hash locally and sends only the first five hex characters to our /api/hibp-check proxy, which forwards that prefix to Have I Been Pwned. Five hex characters match roughly 800 hashes, so neither we nor HIBP can tell which password you typed. The remaining 35 characters of the hash are compared in your browser against the returned list. We keep anonymous counts for rate limiting (30 checks per hour) and log nothing else.
The strength estimate is computed in this tab and the password is never written to the URL, so the shareable link never contains it.
Check it against known breaches
Have I Been Pwned holds over 800 million passwords recovered from real breaches. The lookup uses k-anonymity: your browser computes the SHA-1 hash locally and sends only the first five hex characters of it. That prefix matches roughly 800 hashes, so the server learns nothing about which one is yours — and it never sees the password, the rest of the hash, or anything else.
Generate one instead
What it does
Three things that answer different questions. It estimates how much entropy a candidate password actually has, after discounting the patterns that cracking tools exploit. It checks the candidate against the Have I Been Pwned corpus of breached passwords without sending the password anywhere. And it generates replacements, either as a random passphrase or as a random character string.
The entropy figure is turned into times to guess under three attack models — an online endpoint that rate-limits you, an offline attack against a slow hash, and an offline attack against an unsalted fast hash on GPUs. Those numbers span about fifteen orders of magnitude for the same password, which is the point.
How the breach check keeps the password private
This is the part worth understanding, because “type your password into a website” is normally terrible advice.
Your browser computes the SHA-1 hash of the password locally with
crypto.subtle.digest. It then sends the first five hex characters of that
hash and nothing else. The Pwned Passwords range API returns every hash suffix
in the corpus that begins with those five characters — roughly 800 of them — and
your browser searches that list for the remaining 35 characters. The comparison
happens in the tab. This is the k-anonymity scheme described in the
HIBP API documentation, and
it means the server sees one of 1,048,576 possible prefixes and cannot tell which
of the ~800 matching passwords you were asking about.
Our edge function is a thin proxy that exists only so the request carries a
consistent user agent and the add-padding header, which pads every response to
the same size. It receives the same five characters and stores nothing.
SHA-1 is used because that is what the corpus is keyed on. It is broken for collision resistance, which matters for certificates, and irrelevant here — this is an index lookup, and preimage resistance still holds. It says nothing about how you should store passwords, which is bcrypt, scrypt, or Argon2.
Why the strength number is smaller than you expect
A naive estimator multiplies length by the log of the character-set size and
calls P@ssw0rd! a 59-bit password. Real cracking software does not enumerate
the character space; it runs word lists through mangling rules. Capitalise the
first letter, append a year, swap a for @, add a trailing ! — a standard
ruleset has tens of thousands of these, and it applies all of them to every entry
in a list of hundreds of millions of leaked passwords before it ever tries a
random string.
So this tool discounts what those rules generate for free: keyboard and alphabet runs, characters repeated in a row, a whole password that is one short unit repeated, four digits that look like a year, and the capital-word-digits-symbol shape that composition policies reliably produce. If the input reduces to a commonly leaked password after undoing substitutions, the estimate is capped at roughly the rank of that password in the list, because that is genuinely how many guesses it costs. If the input reads as three or more dictionary words, it is modelled as a word-list attack instead of a character attack.
The result is a heuristic. It is deliberately pessimistic, and the useful signal is the order of magnitude, not the second digit.
When to reach for it
Reach for it when you are picking a password you have to memorise — the one that
unlocks the password manager, the disk, the SSH key — and you want a sanity check
before committing. Reach for it when you suspect a credential has been in a
breach and want confirmation before doing a rotation. Reach for it when someone
proposes a password policy and you want a concrete demonstration that
Winter2025! satisfies every composition rule and is worth about seventeen bits.
Do not paste a live production credential into any web page, including this one. The decoding is local, but clipboard history, browser extensions, and shoulders are not. Check a candidate before you adopt it, not a secret you are already using.
And note what NIST SP 800-63B §5.1.1 actually recommends, since it is the opposite of most corporate policy: a minimum length of 8 with a maximum of at least 64, no composition rules, no mandatory expiry, and a mandatory check against a breach corpus — which is exactly the check on this page.
Related tools
- Hash generator to compute the SHA-1 prefix yourself.
- JWT decoder for the HS256 secrets that need the same treatment.
- UUID generator when you need a random identifier rather than a secret.
- Base64 encoder/decoder for encoding a generated secret into config.
- HTTP header inspector for the rest of a security review.
Frequently asked questions
What exactly gets sent when I run the breach check?+
crypto.subtle.digest, takes the first five hex digits of the 40-digit result, and requests that prefix. The server returns every suffix in the corpus beginning with it — around 800 of them, padded to a uniform response size so the response length itself reveals nothing — and your browser searches that list locally. This is the k-anonymity model HIBP documents. Neither we nor HIBP receive the password or enough of the hash to identify it.Why SHA-1, isn't that broken?+
Not found in the corpus — does that mean my password is good?+
How accurate is the strength number?+
Passphrase or random characters?+
Related tools
Hash Generator
CRC32, MD5, SHA-1, SHA-256, SHA-384, SHA-512 and HMAC over text or a local file. Hex or base64 output, computed in your browser.
JWT Decoder
Decode a JWT header and payload. Optionally verify HS256/RS256 signatures — all client-side.
UUID Generator
Generate v4, time-ordered v7, and Nil UUIDs in bulk, in any format, and inspect an existing UUID for its version, variant, and embedded timestamp.