Breached Password Check

Only five characters of a hash ever leave.

  • Hashed on device
  • Five characters sent
  • Count of sightings
A white rounded padlock with a steel shackle on a pale wooden desk beside a small white tile and a round magnifier lens.

The guide

Five characters of a hash: how to ask a breach list about a password without telling it

A breached-password list is only useful if you can consult it safely. Hashing on your own device and sending a short prefix makes that possible, and shows exactly where the method stops.

  • 5 of 40 characters how much of the SHA-1 hash leaves the device
  • 1,048,576 possible 5-character prefixes, 16 to the power 5
  • 6,421,042 sightings of P@ssw0rd in the reply recorded on 2026-10-20
  • 92 rows padding added to that 2,017-row reply, each with a count of 0
  • 15 characters NIST minimum for a password used on its own
Read the full guide Fold the guide 7 min · 17 sources

Attackers do not guess at random. They start with the passwords that worked before, because people keep choosing them. Every large breach adds to a shared vocabulary of real human choices, and that vocabulary is the first thing a guessing program reaches for.

That is the reason a list of breached passwords is worth having at all. The current NIST guidance on passwords, SP 800-63B-4, tells services that when someone sets or changes a password, the service shall compare it against a blocklist of commonly used, expected or compromised values, and that passwords from previous breach corpuses belong on that list. If the new password is on it, the service shall refuse it and say why. The appendix explains the logic plainly: since people’s choices are predictable, attackers are likely to try passwords that have already proven successful, so the defence is to stop those passwords being chosen in the first place.

A list you cannot simply send your password to

The trouble starts the moment you want to check a password yourself. The biggest public list, Pwned Passwords, holds hundreds of millions of passwords that have appeared in breaches. Sending your real password to any service, however well meant, to ask whether it is on a list of leaked passwords is a strange way to protect it. Downloading the whole list works, but it is large, and few people will do it to check one password.

The answer used today came from a conversation in early 2018. Troy Hunt, who runs Have I Been Pwned, wrote that Junade Ali of Cloudflare suggested using a property called k-anonymity. Version 2 of Pwned Passwords launched on 22 February 2018 with 501,636,842 unique passwords drawn from 3,033,858,815 occurrences, and with a way to search it that never reveals what is being searched for.

The name comes from data privacy research. A release of data is k-anonymous when the information about each person cannot be told apart from that of at least k minus 1 others. Pierangela Samarati and Latanya Sweeney introduced the term in a 1998 paper. Applied to passwords, the idea is that the question you send should match so many possible passwords that the answer reveals nothing about yours.

Five characters out of forty

Here is how the question is built. Your device turns the password into a SHA-1 hash: a fixed 160-bit value, written as 40 hexadecimal characters, defined in the federal Secure Hash Standard, FIPS 180-4. The service stores every password as the SHA-1 of its UTF-8 bytes, so the same password always gives the same hash. Your device sends only the first five characters. There are 16 to the power 5, or 1,048,576, possible prefixes, and the documentation promises that every one of them answers with success; none is ever reported missing.

The reply lists the remaining 35 characters of every hash in the list that begins with your prefix, each followed by a count. Your device searches that reply for its own 35 characters. If it finds them, the count says how often that exact password has been seen in breach data. If it does not, the password is not in the list. The comparison happens on your side, so the service never learns the answer either.

A worked example makes the numbers concrete, and the tool on this page starts with it. The documentation’s own example password is P@ssw0rd. Its SHA-1 hash is 21BD12DC183F740EE76F27B78EB39C8AD972A757, so the request is for the range 21BD1. On 20 October 2026 that request, made with padding switched on, returned 2,017 rows in 79,210 bytes. Of those rows, 1,925 were real hashes and 92 were padding, each carrying a count of 0. The suffix 2DC183F740EE76F27B78EB39C8AD972A757 sat on row 342 with a count of 6,421,042. Press Check on the same password today and you will get a fresh count; the totals only grow.

Watching that one count over time tells its own story. Troy Hunt’s padding article from March 2020 shows the same range returning 528 results, with P@ssw0rd seen 52,579 times. His 2022 article on SHA-1 shows it at 83,129. Our recorded reply puts it above six million. The password did not get worse; the list got bigger. A count is a measure of what has been collected, not a fixed property of the password.

So read a count as a lower bound on exposure, never as a ranking of how bad a password is. Any number above zero carries the same instruction.

So what did the service learn from that request? Only that someone, somewhere, asked about a hash beginning 21BD1. The reply alone carried 1,925 known candidates, and an unbounded number of strings that have never leaked share the same prefix. Hunt’s padding article gives two of the known neighbours, the passwords 020293 and sparky50, whose hashes also begin 21BD1. The service cannot tell which, if any, you hold.

Padding, and why the prefix is not nothing

The first version had a gap that nobody could see by reading the requests. HTTPS hides the content of a reply, but not its size. Because different prefixes return different numbers of rows, someone watching encrypted traffic could compare reply sizes and narrow down which prefix was asked about. The fix, added in 2020, is a request header, Add-Padding, that tells the service to append random rows with a count of zero. The documentation says those rows can be discarded once received, and a careful client discards them. The padded reply above was 3,588 bytes longer than the same request without padding.

The prefix itself is not free of information, and it is worth being honest about that. A 2019 study of what its authors call compromised credential checking services found that, in some settings, knowing the hash prefixes made remote guessing attacks twelve times as effective. The authors, including Junade Ali, proposed two stronger protocols. The practical lessons for anyone checking a password are simple: check rarely, and never check as you type. The documentation warns that a request for every keystroke could let an observer work out the password, which is why the tool here sends nothing until a button is pressed.

The hash algorithm also draws questions. SHA-1 is broken for its original job: in 2017 a team published the first known collision, two different PDF files with the same SHA-1 hash, and NIST announced in December 2022 that it should be phased out by 31 December 2030 in favour of SHA-2 and SHA-3. Here, though, it does not sign or certify anything. It splits the list into roughly equal buckets and hides badly parsed breach lines, the two reasons Hunt gives for using it. The browser’s own SubtleCrypto interface still computes it, with a warning not to rely on it for cryptography, which is exactly the role it does not play here.

What a match means

A match is a clear verdict. If the count is 1, the password has still appeared in breach data and sits in the lists that guessing tools load first. Under the NIST rules a service should refuse it, and the right response is to stop using it everywhere. Treat any count above zero as a reason to change it.

The second half of that advice matters more than the first. Credential stuffing is an attack that does not guess at all: it replays username and password pairs from one breach against many other sites, and it works because people reuse passwords. A unique password per account turns a breach at one site into a problem for that one account. Nobody can remember dozens of long random passwords, which is why CISA advises using a password manager to create and store them, and why NIST requires services to allow password managers and autofill, noting that managers make stronger passwords more likely.

That leads to the most important point about this whole method. A password manager that generates a long random password for each site makes this check almost pointless for those passwords. A freshly drawn random password has essentially no chance of being on any list, because no one has ever used it. The check earns its keep on the passwords people chose themselves, and on old ones that have been in use for years.

What the check cannot tell you

Not found is a statement about one list, and nothing more. It does not mean the password is strong: a short password, a name and a year, or a keyboard pattern can be absent today and still fall to a guessing program in seconds. NIST asks for at least 15 characters for a password used on its own, and 8 only where a second factor is also required. It also does not mean the password has never leaked. Breaches that were never made public, or never reached this collection, are invisible to it.

Small details can also make two passwords that look the same hash differently. Some accented letters can be typed as one character or as a letter plus a combining mark. NIST asks services to apply Unicode normalization form NFC before hashing; the list itself states only that it hashes UTF-8. When the two forms differ, the tool offers both, so you can check each.

The check also trusts the network path it uses. The page that runs it adds exactly one outside origin for this purpose to the connect-src rule of its content security policy, so the browser refuses any destination that rule does not list. Nothing on the page can make the service honest, of course. What k-anonymity guarantees is narrower and sturdier: even a dishonest service only ever sees five characters.

Used that way, a breached-password check is a small, sharp tool. It answers one question well, whether this exact password is already in the hands of people who collect them, and it answers without asking you to trust anyone with the password. Everything beyond that question, from strength to reuse, still depends on how the password was made.

Sources

Every source consulted for this guide. Links checked October 20, 2026.

  1. Have I Been Pwned: API Documentation Have I Been Pwned (Troy Hunt)
  2. Pwned Passwords Have I Been Pwned
  3. I've Just Launched "Pwned Passwords" V2 With Half a Billion Passwords for Download Troy Hunt (CC BY 4.0)
  4. Enhancing Pwned Passwords Privacy with Padding Troy Hunt (CC BY 4.0)
  5. Understanding Have I Been Pwned's Use of SHA-1 and k-Anonymity Troy Hunt (CC BY 4.0)
  6. NIST Special Publication 800-63B National Institute of Standards and Technology (SP 800-63B-4)
  7. FIPS PUB 180-4, Secure Hash Standard (SHS) National Institute of Standards and Technology
  8. RFC 3174: US Secure Hash Algorithm 1 (SHA1) IETF (D. Eastlake 3rd, P. Jones)
  9. NIST Retires SHA-1 Cryptographic Algorithm National Institute of Standards and Technology
  10. SubtleCrypto: digest() method MDN Web Docs, Mozilla
  11. Content-Security-Policy: connect-src directive MDN Web Docs, Mozilla
  12. String.prototype.normalize() MDN Web Docs, Mozilla
  13. k-anonymity Wikipedia
  14. The first collision for full SHA-1 IACR Cryptology ePrint Archive (Stevens, Bursztein, Karpman, Albertini, Markov; CC BY)
  15. Credential stuffing Wikipedia
  16. Protocols for Checking Compromised Credentials arXiv (Li, Pal, Ali, Sullivan, Chatterjee, Ristenpart)
  17. Use Strong Passwords Cybersecurity and Infrastructure Security Agency (CISA)