Password Security in 2025 — Most Sites Are Still Doing This Wrong

If your password requirements look like this: "Must contain uppercase, lowercase, a number, and a special character" — you're implementing a policy that NIST officially deprecated in 2017 and that security researchers had been criticizing for years before that.

It feels secure. It isn't. And the reason it fails is actually pretty interesting.

Why Complexity Rules Backfire

When users hit a complexity requirement, they don't generate a genuinely random password. They pick a word they like and mutate it. "password" becomes "P@ssw0rd!" — uppercase check, special character check, number check, done. Every attacker's wordlist includes hundreds of thousands of these substitution patterns.

NIST SP 800-63B acknowledged this in 2017 and explicitly dropped the complexity requirement recommendation. The reason is entropy. A password's real strength is its unpredictability. "P@ssw0rd!" might satisfy four complexity rules but it has maybe 18 bits of entropy. A random 4-word passphrase has around 44 bits. The passphrase wins, badly, even though it has no special characters.

Entropy Is the Number That Actually Matters

Every bit of entropy doubles the search space an attacker has to cover.

• Lowercase only (26 chars): ~4.7 bits per character • Lowercase + uppercase (52 chars): ~5.7 bits per character • Full alphanumeric (62 chars): ~5.95 bits per character • Full printable ASCII (95 chars): ~6.57 bits per character

A 16-character random password from the full ASCII character set gives you roughly 105 bits of entropy. That's not crackable with any hardware that currently exists. The character set matters less than length. Length matters a lot.

The rule that actually improves security: enforce minimum length aggressively — 12 characters as a hard floor, 16+ as the recommendation. Drop the complexity rules. Allow up to 64 characters minimum.

What NIST 800-63B Actually Says to Do

The current federal standard recommendations developers should be following:

• Minimum 8 characters for user-chosen passwords (but treat this as a floor, not a goal) • Allow at least 64 characters maximum • Check new passwords against known compromised password lists • Do NOT enforce complexity rules • Do NOT force periodic password rotation unless there's evidence of compromise • Allow paste into password fields (so password managers work)

That last one is critical and routinely ignored. Blocking paste in password fields is actively harmful because it makes password managers harder to use. There is no security benefit. Stop doing it.

The Single Best Thing You Can Add: HaveIBeenPwned Integration

The Pwned Passwords database has over 800 million compromised passwords collected from real data breaches. Checking new password submissions against it is the single highest-impact change you can make to your password validation.

The API uses k-Anonymity — you send only the first 5 characters of the SHA-1 hash, never the password itself:

echo -n "yourpassword" | sha1sum # Returns: abc123... curl https://api.pwnedpasswords.com/range/ABC12 # Check if the rest of your hash appears in the response

Reject any password that appears in the list, regardless of how complex it looks. A password with exclamation marks that appeared in 2 million breaches is dangerous.

Check Strength and Generate Secure Passwords

Need to test how strong a password actually is, or generate a truly random one? Our free tools handle both — no signup required:

Test password strength or generate a secure password instantly

Password Strength Checker → Password Generator →

FAQs

No. NIST explicitly removed this recommendation. Forced rotation causes users to make predictable incremental changes (password1 → password2 → password3) and increases support burden without improving security. Only require a change if you have actual evidence of compromise.
Argon2id is the current recommendation for new implementations — it won the Password Hashing Competition in 2015. bcrypt and scrypt are also acceptable. Never MD5, never SHA-1, never any unsalted hash of any kind. Set the work factor high enough that hashing takes ~100ms on your servers.
Yes, absolutely. Rate limiting is one of the most important defenses you have. IP-based rate limiting, account-level lockout after N failures, CAPTCHA on repeated attempts, alerts for unusual geographic access patterns. Combine it with good password requirements, not instead of them.
Scroll to Top
Checker Tools