Skip to content
Control Plane Labs

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.

Frequently asked questions

What exactly gets sent when I run the breach check?+
Five characters. Your browser hashes the password with SHA-1 via 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?+
SHA-1 is broken for collision resistance, which matters for signatures and certificates. Here it is only a lookup index into a fixed corpus, and preimage resistance — the property that would let someone recover your password from the hash — is intact. It is also not a choice: HIBP's Pwned Passwords range API is keyed on SHA-1, so the prefix has to be a SHA-1 prefix. None of this bears on how a password should be stored, which is bcrypt, scrypt, or Argon2.
Not found in the corpus — does that mean my password is good?+
No. It means the password has not turned up in a dataset HIBP has ingested. A password can be trivially guessable and absent from every breach, which is why the entropy estimate and the breach check are separate answers to separate questions. The breach check tells you whether credential stuffing finds it immediately; the entropy estimate tells you how long brute force would take. You want to pass both.
How accurate is the strength number?+
Treat it as an order of magnitude, not a measurement. It starts from character-class entropy, applies penalties for the patterns crackers exploit — keyboard runs, repeated units, years, the capital-word-digit-symbol shape — and caps the result when the input matches a commonly leaked password or reads as a sequence of dictionary words. A dedicated estimator with a large corpus will disagree at the margins. The gap between 25 bits and 80 bits is what matters, not the gap between 62 and 67.
Passphrase or random characters?+
Whichever you will actually use. A five-word passphrase from this generator is around 54 bits and you can retype it from memory; twenty random characters is about 120 bits and you cannot. NIST SP 800-63B §5.1.1 dropped composition rules and mandatory rotation precisely because they pushed people toward short, predictable, written-down passwords. For anything you are not memorising, use a password manager and generate the long random one.