Has Your Password Been Leaked? How to Check Without Revealing It
"123456" has leaked 210 million times. How to check whether your password has been breached without sending it anywhere, and how websites should store passwords.

Contents 8
The password "123456" has appeared in known data breaches exactly 210,461,208 times. "password" shows up 52,372,427 times, "qwerty" 30,812,897 times. If you're wondering whether your password has been leaked, here is the interesting part: you can find out without sending your password to any website. In this post we explain that mathematical trick, give you a check you can run on your own computer, and show how websites should actually store your password.
In short:
- Have I Been Pwned's Pwned Passwords service lets you check hundreds of millions of breached passwords for free.
- You send only the first 5 characters of your password's hash, never the password itself; this is called k-anonymity.
- A good website never stores your password as plain text, but as a salted hash made with a slow algorithm such as Argon2id.
- NIST's current rules: at least 15 characters for passwords used alone, no forced periodic changes, and breached passwords must be rejected.
Which passwords leak the most?
We queried the numbers below ourselves from the Pwned Passwords service while preparing this post (September 30, 2026). Each number shows how many times that password appears in known breach data:
| Password | Times seen in breaches |
|---|---|
| 123456 | 210,461,208 |
| 123456789 | 81,108,282 |
| 12345678 | 70,606,130 |
| password | 52,372,427 |
| qwerty | 30,812,897 |
| asdasd | 3,129,629 |
| galatasaray | 298,542 |
| fenerbahce | 246,005 |
| besiktas | 121,469 |
The last three are the names of Turkey's biggest football clubs, a reminder that favourite teams are as predictable as 123456. If you see one of your passwords here, know that it sits at the very top of attackers' guess lists. Attackers don't guess passwords one by one; they try leaked lists like these first. Team names, birth years and keyboard patterns (asdasd, qwerty) fall within seconds for that reason.
How can you check a password without sending it?
At first glance it looks like a paradox: doesn't a service need to know your password to find it in a breach list? It doesn't. The method has three steps.
1. You hash the password. A hash is a one-way function that turns data into a fixed-length fingerprint. The SHA-1 hash of the word password is:
5BAA61E4C9B93F3F0682250B6CF8331B7EE68FD8
There is no direct way back from the hash to the password, but the same password always produces the same hash.
2. You send only the first 5 characters of the hash. In the example above that is 5BAA6. You simply ask the service: "give me the hashes that start with 5BAA6."
3. You do the comparison on your own computer. The service returns the rest of every hash starting with 5BAA6, along with how many times each was seen. In our tests each request returned roughly 2,000 lines. You look for the rest of your own hash (1E4C9B93F3F...) in that list.
On the service's side, a 5-character prefix matches about 2,000 different passwords. It can't tell which one you asked about, and your password may not be in the list at all. This is called k-anonymity: your query gets lost among thousands of other possibilities.
Have I Been Pwned goes one step further. If you add the Add-Padding: true header to the request, fake lines with a count of 0 are added to the response, and your code simply ignores them. That way someone watching the network can't guess which prefix you asked for from the size of the response.
Try it on your own computer
To find out yourself whether your password has been leaked, the Python code below is all you need; it implements the three steps above. It needs no extra library and no API key. The password isn't shown on screen while you type it, and the password itself never leaves your computer:
import getpass, hashlib, urllib.request
password = getpass.getpass("Password: ") # hidden while you type
digest = hashlib.sha1(password.encode("utf-8")).hexdigest().upper()
prefix, suffix = digest[:5], digest[5:]
request = urllib.request.Request(
"https://api.pwnedpasswords.com/range/" + prefix,
headers={"User-Agent": "password-check", "Add-Padding": "true"},
)
response = urllib.request.urlopen(request).read().decode()
for line in response.splitlines():
s, count = line.split(":")
if s == suffix and int(count) > 0:
print(f"This password has been seen {int(count):,} times in breaches. Change it now!")
break
else:
print("This password is not in any known breach.")
Save it as check.py and run it with python check.py. A "not in any known breach" result doesn't mean the password is strong; it only means it isn't on the known lists.
How should websites store your password?
The critical question in any breach story is what state the passwords were in. There are three levels:
- Plain text: The password sits in the database as is. The moment the database leaks, every password can be read. Unacceptable.
- Fast hash (MD5, SHA-1, SHA-256): The password is hashed, but these algorithms are designed for speed. As OWASP puts it, fast hashes let attackers make a huge number of guesses very quickly. The breached password lists above are the shortest route to cracking such hashes.
- Slow, salted hash (Argon2id, scrypt, bcrypt): A random salt is added to each password and hashing is deliberately slow, even memory-hard. Even two users with the same password end up with different hashes; precomputed tables (rainbow tables) are useless and every guess is expensive for the attacker.
OWASP's password storage guide currently recommends these settings:
| Algorithm | Minimum recommended setting | When |
|---|---|---|
| Argon2id | 19 MiB memory, 2 iterations, 1 degree of parallelism | First choice |
| scrypt | N=2^17, r=8, p=1 | If Argon2id isn't available |
| bcrypt | Work factor 10 or more, passwords up to 72 bytes | Legacy systems |
| PBKDF2 | 600,000+ iterations with HMAC-SHA-256 | When FIPS-140 compliance is required |
The subtle point is that even an algorithm known as "secure", like SHA-256, is the wrong tool for storing passwords. A strong hash isn't enough; it has to be slow.
The password rules have changed: what does NIST say?
"At least one uppercase letter, one digit, one special character, and change it every 90 days." For years these rules were treated as standard. The current version of SP 800-63B, the digital identity guideline of the US National Institute of Standards and Technology (NIST), reverses most of them:
- Length is what matters: Passwords used on their own must be at least 15 characters. For passwords that are part of multi-factor authentication, the minimum is 8.
- Allow long passwords: Systems should accept passwords of at least 64 characters.
- No composition rules: Rules like "mix uppercase, digits and symbols" must not be imposed.
- No forced periodic changes: Users must not be asked to change passwords at regular intervals; a change is required only when there is evidence the password has been compromised.
- Reject breached passwords: A new password must be compared against a blocklist of known breached and common passwords, and if it's on the list it must be rejected with the reason explained.
The last point brings the k-anonymity method from the start of this post straight into sign-up forms. When a user types "password", the system can say "this password has been seen 52 million times in breaches" instead of accepting it.
What should you do to protect yourself?
- Use a password manager. You don't have to memorise a different, long, random password for every site; the manager generates and remembers them for you.
- Choose long passphrases. A 15+ character phrase made of a few randomly chosen words is both stronger and easier to remember than a short, complex password.
- Don't reuse passwords. A breach on one site opens every other account where you used the same password.
- Turn on two-step verification. Even if your password leaks, nobody can sign in without the second factor.
- Check your email too. On Have I Been Pwned's home page you can see which breaches your email address appears in.
Frequently asked questions
Is it safe to type my password into Have I Been Pwned?
The Pwned Passwords page and API send only the first 5 characters of your password's SHA-1 hash, not the password itself. The service can't tell your password apart from the thousands of possibilities that share that prefix. If you still aren't comfortable, you can read the Python code above and run it on your own computer.
If my password isn't on the list, am I safe?
Not entirely. The list only covers known breaches. A short or predictable password (a name, a birth date) can be cracked quickly even if it isn't on the list. Length and uniqueness are still the two most important rules.
Isn't SHA-1 broken? Why is it still used?
SHA-1 is no longer considered safe against collision attacks and must never be used to store passwords. In Pwned Passwords, SHA-1 only serves as an "address" for searching without revealing the password; collision attacks don't matter for that use.
Should I change my password regularly?
According to NIST's current guideline, no. Forced periodic changes push people toward small, predictable tweaks (Password2025! → Password2026!). Change your password right away when you think it has leaked or been compromised.
What decides the damage of a breach is usually not the breach itself, but how the passwords were stored. If you want to build a web application that protects user data the right way, reach out to us through our web application development page.


