Password policies have undergone a radical transformation in recent years. The old rules ā forced special characters, mandatory 90-day rotations, security questions ā have been officially retired by NIST (National Institute of Standards and Technology). In their place, a new evidence-based approach focuses on length, breach-list checking, and multi-factor authentication. This comprehensive guide covers everything you need to know about modern password requirements in 2025, from the latest NIST SP 800-63B guidelines to practical implementation strategies.
1. NIST SP 800-63B: What Changed
NIST Special Publication 800-63B (Digital Identity Guidelines: Authentication and Lifecycle Management) was first revised in 2017 and updated through 2024. It fundamentally changed how organizations should think about password security. The key insight: most traditional password rules made passwords harder for humans but not meaningfully harder for attackers.
NIST explicitly states that verifiers SHALL NOT require periodic password changes unless there is evidence of compromise. Research showed that forced rotation leads to predictable patterns: users append incrementing numbers (Password1, Password2, Password3) or make minimal changes that attackers can easily guess. A strong password that is not compromised does not become weaker over time.
NIST removed the requirement for specific character types (uppercase, lowercase, digits, special characters). These rules led to predictable patterns like "Password1!" that satisfy complexity requirements but are trivially guessable. Instead, NIST emphasizes length and checking against known-compromised passwords.
Security questions like "What is your mother's maiden name?" are no longer acceptable. This information is often publicly available or easily guessable. NIST requires that memorized secret verifiers SHALL NOT use knowledge-based authentication (KBA) for verification.
When a user sets or changes a password, NIST requires that the password SHALL be compared against a list of commonly-used, expected, or compromised values. This includes passwords from previous breach corpuses, dictionary words, repetitive or sequential characters, and context-specific words like the service name or username.
# NIST SP 800-63B Summary of Key Changes
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā
ā REMOVED (SHALL NOT) ā ADDED (SHALL / SHOULD) ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¼āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā¤
ā Forced periodic rotation ā Check against breach lists ā
ā Composition rules (upper+lower ā Minimum 8 chars (12+ better) ā
ā +digit+special) ā Allow 64+ character passwords ā
ā Password hints ā Accept all Unicode + spaces ā
ā Security questions (KBA) ā Allow paste in password fields ā
ā Truncating passwords ā Offer "show password" option ā
ā SMS as primary 2FA (restricted) ā Use approved hash algorithms ā
āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā“āāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāāā2. Minimum Length: 8 Is Dead, 12-16 Is the New Standard
NIST SP 800-63B requires a minimum of 8 characters for user-chosen passwords, but security experts and modern frameworks have moved well beyond this floor. The mathematical reality is simple: every additional character exponentially increases the search space an attacker must cover.
Here is how password length affects brute-force time assuming 95 printable ASCII characters and an attacker hashing at 10 billion attempts per second (modern GPU cluster against a fast hash):
| Password Length | Possible Combinations | Time to Brute Force | Verdict |
|---|---|---|---|
| 6 chars | 95^6 = 735 billion | ~1.2 minutes | Instantly crackable |
| 8 chars | 95^8 = 6.6 quadrillion | ~7.6 days | Too weak for 2025 |
| 10 chars | 95^10 = 59.9 quintillion | ~190 years | Minimum acceptable |
| 12 chars | 95^12 = 540 sextillion | ~1.7 million years | Good |
| 16 chars | 95^16 = 44 octillion | ~139 trillion years | Excellent |
| 20 chars | 95^20 = 3.6 x 10^39 | ~11.4 x 10^21 years | Overkill (but great) |
Note: Important: These calculations assume a fast hash like SHA-256. With a proper password hashing algorithm like Argon2id (which reduces attacker speed to roughly 1,000 hashes/sec), even an 8-character password takes significantly longer. However, length remains the single most effective defense against brute-force attacks.
Modern recommendations by organization:
- NIST SP 800-63B: Minimum 8 characters (but recommends allowing up to 64+)
- OWASP: Minimum 8 characters, recommends 12+
- PCI-DSS v4.0: Minimum 12 characters (increased from 7 in v3.2)
- Microsoft: Minimum 12 characters for Azure AD
- Google: Minimum 8 characters, recommends 12+
Best practice for 2025: Set your minimum to 12 characters. Allow (and encourage) up to 64 or more. Never truncate passwords.
3. What NIST Recommends: Allow All Characters, Check Breach Lists, No Hints
The NIST guidelines take a fundamentally different approach than traditional password policies. Instead of making passwords hard to create, they focus on making passwords hard to guess.
Verifiers SHALL accept all printable ASCII characters, the space character, and all Unicode characters (including emoji). There SHALL be no rules limiting which characters can appear where. This enables passphrases, non-English passwords, and creative password construction.
Verifiers SHALL permit passwords of at least 64 characters in length. There is no reason to set an upper limit below this. Longer passwords should be encouraged through UI design ā show a strength meter that rewards length rather than complexity.
When a user creates or changes a password, check it against a list of known-compromised passwords. If the password appears in a breach database, reject it and explain why. The Have I Been Pwned API provides a free, privacy-preserving way to do this using k-anonymity.
Verifiers SHALL NOT truncate passwords. Every character the user enters must be part of the stored hash. Bcrypt has a 72-byte limit ā if using bcrypt, pre-hash the password with SHA-256 before passing it to bcrypt.
Verifiers SHALL NOT use password hints, security questions, or knowledge-based authentication. These provide attack vectors that undermine password security. Use email-based or MFA-based account recovery instead.
Verifiers SHOULD allow users to temporarily display (unmask) their password while typing. This reduces errors from hidden input and helps users create and enter long, complex passwords correctly.
4. What NIST Removed: Forced Special Characters, Periodic Expiration, Security Questions
Understanding what was removed is just as important as understanding what was added. Each removed requirement was based on assumptions that research proved wrong.
The old requirement to include at least one uppercase, one lowercase, one digit, and one special character led to entirely predictable patterns. "Password1!" satisfies every traditional complexity rule while being one of the most commonly breached passwords. Users overwhelmingly place the uppercase letter first, the digit near the end, and the special character at the very end. Attackers know this and optimize their cracking strategies accordingly.
Forcing users to change passwords every 30, 60, or 90 days causes security fatigue and predictable password mutations. A Carnegie Mellon University study found that users who were forced to change passwords chose passwords that were statistically similar to their previous ones, making them vulnerable to targeted guessing. NIST now says: change passwords only when there is evidence of compromise.
Security questions are fundamentally broken. The answers to questions like "What is your mother's maiden name?" or "What city were you born in?" are often publicly available through social media, public records, or data breaches. Even "secret" questions like "What is your favorite movie?" have a surprisingly small answer space. Google research showed that 19.7% of English speakers would answer "pizza" to "What is your favorite food?".
While NIST did not remove SMS 2FA entirely, it is classified as a "restricted" authenticator due to known vulnerabilities: SIM swapping, SS7 protocol attacks, and social engineering of carrier employees. NIST recommends app-based TOTP or hardware security keys instead.
The pattern is clear: NIST removed requirements that created a false sense of security while adding friction for legitimate users. Every removed rule was replaced with evidence-based guidance that actually improves security.
5. Entropy Calculator: How to Estimate Password Strength in Bits
Password entropy measures the unpredictability of a password in bits. Higher entropy means the password is harder to guess. Entropy is calculated as: H = log2(R^L), where R is the size of the character pool and L is the password length.
# Password Entropy Formula
H = log2(R^L) = L * log2(R)
Where:
H = Entropy in bits
R = Size of the character pool
L = Password length
# Example: 12-character password using full ASCII (95 chars)
H = 12 * log2(95) = 12 * 6.57 = 78.8 bits
# Example: 4-word Diceware passphrase (7776-word list)
H = 4 * log2(7776) = 4 * 12.92 = 51.7 bitsCharacter Pool Sizes
| Pool | Size (R) | Example |
|---|---|---|
| Digits only (0-9) | 10 | 0-9 |
| Lowercase letters (a-z) | 26 | a-z |
| Upper + lowercase (A-Za-z) | 52 | A-Za-z |
| Alphanumeric (A-Za-z0-9) | 62 | A-Za-z0-9 |
| Full printable ASCII | 95 | !-~, space |
| Diceware word list | 7,776 | correct, horse, battery... |
Entropy Calculations for Common Passwords
| Password Type | Length | Entropy Formula | Entropy (bits) | Strength |
|---|---|---|---|---|
| 4-digit PIN | 4 | log2(10^4) | 13.3 bits | Very Weak |
| 6-char lowercase | 6 | log2(26^6) | 28.2 bits | Weak |
| 8-char mixed case + digits | 8 | log2(62^8) | 47.6 bits | Moderate |
| 12-char full ASCII | 12 | log2(95^12) | 78.8 bits | Strong |
| 16-char full ASCII | 16 | log2(95^16) | 105.1 bits | Very Strong |
| 4-word passphrase (Diceware) | 4 words | log2(7776^4) | 51.7 bits | Moderate |
| 6-word passphrase (Diceware) | 6 words | log2(7776^6) | 77.5 bits | Strong |
| 8-word passphrase (Diceware) | 8 words | log2(7776^8) | 103.4 bits | Very Strong |
Note: These calculations assume truly random password generation. Human-chosen passwords have much lower effective entropy because humans are predictable ā they use dictionary words, names, dates, and common substitutions (aā@, eā3). A password strength meter that only checks length and character classes will drastically overestimate the entropy of human-chosen passwords.
Target entropy levels for 2025:
- Online attacks (rate-limited): 30+ bits is sufficient with account lockout
- Offline attacks (stolen hash, fast hash): 60+ bits minimum
- Offline attacks (stolen hash, Argon2id): 40+ bits is acceptable
- High-security accounts: 80+ bits recommended
6. Comparison Table: NIST vs OWASP vs PCI-DSS vs Old Standards
Different standards and frameworks have different requirements. Here is how they compare as of 2025:
| Requirement | NIST SP 800-63B (2024) | OWASP ASVS v4.0 | PCI-DSS v4.0 | Traditional (pre-2017) |
|---|---|---|---|---|
| Minimum Length | 8 characters | 8 characters (12+ recommended) | 12 characters | 6-8 characters |
| Maximum Length | 64+ characters | 128+ characters | Not specified | Often 16-20 characters |
| Complexity Rules | SHALL NOT require | Not required | Numeric + alphabetic | Upper + lower + digit + special |
| Forced Rotation | SHALL NOT require | Not recommended | Every 90 days (if no MFA) | Every 30-90 days |
| Breach List Check | SHALL check | Required | Not required | Not required |
| MFA | Required for AAL2+ | Required for Level 2+ | Required for admin access | Optional |
| Password Hints | SHALL NOT use | Prohibited | Not addressed | Commonly used |
| Password Hashing | Approved algorithms only | Argon2id, bcrypt, scrypt | Strong one-way hash | MD5 or SHA-1 common |
| Unicode Support | SHALL accept | Required | Not addressed | Often ASCII-only |
Key takeaway: NIST leads the way with the most modern, evidence-based approach. PCI-DSS v4.0 still requires complexity rules and periodic rotation (unless MFA is used), reflecting its slower adoption of research-based recommendations. If you can only follow one standard, choose NIST SP 800-63B.
7. Passphrase vs Password: Why "correct horse battery staple" Wins
The famous XKCD comic (#936) made a compelling case for passphrases over passwords. The math supports it: a randomly selected 4-word passphrase from a 7,776-word Diceware list has 51.7 bits of entropy ā comparable to a random 8-character mixed-case alphanumeric password ā while being dramatically easier to remember.
Passphrase vs Traditional Password Comparison
| Type | Example | Entropy | Memorability | Typing Ease |
|---|---|---|---|---|
| Traditional complex | j7#Kp!2x | ~52 bits | Very hard | Slow, error-prone |
| 4-word Diceware | correct horse battery staple | ~52 bits | Easy | Fast, natural |
| 6-word Diceware | atlas usable flock dizzy clout snare | ~78 bits | Moderate | Fast, natural |
| 8-word Diceware | embody quote cider clap virus gag yoyo wheat | ~103 bits | Harder | Fast, natural |
Why passphrases are better:
- Equal or greater entropy: A 4-word passphrase matches an 8-character random password in entropy. A 6-word passphrase exceeds most traditional passwords.
- Easier to remember: Humans are better at remembering sequences of words than random characters. A passphrase creates a mental image.
- Easier to type: Especially on mobile devices, typing words is faster and less error-prone than switching between character types.
- Resistant to shoulder surfing: A long string of words is harder to memorize from a brief glance than a short random string.
- Naturally long: Even a 4-word passphrase is typically 20+ characters, providing excellent protection against brute-force attacks.
Warning: Warning: The passphrase words MUST be randomly selected, not chosen by the user. Human-chosen phrases like "iloveyouforever" or "letmeinplease" have extremely low entropy because attackers know common phrases. Use a Diceware word list with actual dice or a cryptographically secure random number generator.
How to generate a Diceware passphrase:
- Get a Diceware word list (7,776 words, each mapped to a 5-digit dice roll).
- Roll 5 dice (or one die 5 times) for each word you need.
- Look up each 5-digit number in the word list.
- Combine the words with spaces. That is your passphrase.
- For most purposes, 5-6 words provide excellent security (64.6 - 77.5 bits).
# Diceware passphrase generation example
$ dice rolls: 1-6-2-3-4 ā "atlas"
$ dice rolls: 5-4-1-1-6 ā "usable"
$ dice rolls: 2-5-3-1-2 ā "flock"
$ dice rolls: 2-1-4-6-5 ā "dizzy"
Passphrase: "atlas usable flock dizzy"
Entropy: 4 * log2(7776) = 51.7 bits
Length: 24 characters (spaces included)
# Compare to traditional password
"j7#Kp!2x" = 8 chars * log2(95) = 52.6 bits
# Same entropy, but much harder to remember and type!8. Implementing Password Policies: Bcrypt Cost, Rate Limiting, MFA
Knowing the guidelines is one thing; implementing them correctly is another. Here is a practical checklist for implementing a modern, NIST-compliant password policy in 2025.
Password Hashing
Choose Argon2id as your primary hashing algorithm. If Argon2id is not available, use bcrypt with a cost factor of 12 or higher. Target 200-500ms per hash on your production hardware. Never use MD5, SHA-1, SHA-256, or any fast hash function for password storage.
// Argon2id configuration (OWASP recommended)
const argon2 = require('argon2');
const hashConfig = {
type: argon2.argon2id,
memoryCost: 19456, // 19 MiB
timeCost: 2, // 2 iterations
parallelism: 1, // 1 thread
};
// Hash on registration
const hash = await argon2.hash(password, hashConfig);
// Verify on login
const isValid = await argon2.verify(hash, password);
// āā Bcrypt alternative (if Argon2 unavailable) āā
const bcrypt = require('bcrypt');
const COST_FACTOR = 12; // Target: 200-500ms
const bcryptHash = await bcrypt.hash(password, COST_FACTOR);
const bcryptValid = await bcrypt.compare(password, bcryptHash);Rate Limiting
Implement rate limiting on authentication endpoints to prevent online brute-force attacks. After 5-10 failed attempts, introduce progressive delays or temporary account lockout. Use a CAPTCHA after 3 failed attempts. Implement IP-based rate limiting (e.g., 100 attempts per IP per hour) and account-based rate limiting (e.g., 10 attempts per account per 15 minutes).
// Rate limiting example (Express.js with express-rate-limit)
const rateLimit = require('express-rate-limit');
// IP-based rate limiting
const loginLimiter = rateLimit({
windowMs: 15 * 60 * 1000, // 15 minutes
max: 10, // 10 attempts per IP per window
message: 'Too many login attempts. Please try again later.',
standardHeaders: true,
legacyHeaders: false,
});
// Account-based rate limiting (in-memory example)
const accountAttempts = new Map();
async function checkAccountRateLimit(username) {
const key = username.toLowerCase();
const attempts = accountAttempts.get(key) || { count: 0, lastAttempt: 0 };
if (attempts.count >= 5) {
const cooldown = 15 * 60 * 1000; // 15 minutes
if (Date.now() - attempts.lastAttempt < cooldown) {
throw new Error('Account temporarily locked. Try again later.');
}
attempts.count = 0; // Reset after cooldown
}
return attempts;
}
app.post('/login', loginLimiter, async (req, res) => {
const { username, password } = req.body;
const attempts = await checkAccountRateLimit(username);
const isValid = await verifyPassword(username, password);
if (!isValid) {
attempts.count++;
attempts.lastAttempt = Date.now();
accountAttempts.set(username.toLowerCase(), attempts);
return res.status(401).json({ error: 'Invalid credentials' });
}
accountAttempts.delete(username.toLowerCase());
// ... generate session / JWT
});Multi-Factor Authentication (MFA)
MFA is the single most effective defense against credential-based attacks. Even if an attacker obtains a password (through phishing, breach reuse, or brute force), MFA blocks unauthorized access. Prefer app-based TOTP (Google Authenticator, Authy) or hardware keys (YubiKey, Passkeys) over SMS-based 2FA.
Server-Side Validation Checklist
Bcrypt / Argon2id Cost Tuning
The cost parameter should be tuned to your specific hardware. Run benchmarks on your production server and choose a cost that results in 200-500ms per hash. This provides a good balance between user experience (login latency) and attacker cost.
# Benchmarking password hashing on your server
# Goal: 200-500ms per hash
# Node.js benchmark script
const argon2 = require('argon2');
const bcrypt = require('bcrypt');
async function benchmark() {
const password = 'benchmarkPassword123';
// Argon2id benchmarks
for (const mem of [19456, 47104, 65536]) {
const start = Date.now();
for (let i = 0; i < 10; i++) {
await argon2.hash(password, {
type: argon2.argon2id,
memoryCost: mem,
timeCost: 2,
parallelism: 1,
});
}
const avg = (Date.now() - start) / 10;
console.log(`Argon2id (m=${mem}): ${avg.toFixed(0)}ms`);
}
// Bcrypt benchmarks
for (const cost of [10, 11, 12, 13, 14]) {
const start = Date.now();
for (let i = 0; i < 10; i++) {
await bcrypt.hash(password, cost);
}
const avg = (Date.now() - start) / 10;
console.log(`Bcrypt (cost=${cost}): ${avg.toFixed(0)}ms`);
}
}
benchmark();
# Expected output (varies by hardware):
# Argon2id (m=19456): ~150ms
# Argon2id (m=47104): ~350ms ā Good target
# Argon2id (m=65536): ~500ms
# Bcrypt (cost=10): ~75ms
# Bcrypt (cost=11): ~150ms
# Bcrypt (cost=12): ~300ms ā Good target
# Bcrypt (cost=13): ~600ms
# Bcrypt (cost=14): ~1200ms9. Checking Against Breach Databases: Have I Been Pwned API, k-Anonymity
One of NIST's most impactful requirements is checking passwords against known breach databases. The Have I Been Pwned (HIBP) Passwords API makes this both practical and privacy-preserving using a technique called k-anonymity.
How k-Anonymity Works
The HIBP Passwords API never sees the actual password or even the full hash. Instead, it uses a range search based on the first 5 characters of the SHA-1 hash:
- Hash the password with SHA-1 (used only for lookup, not for storage).
- Send only the first 5 characters of the hex-encoded hash to the HIBP API.
- The API returns all hash suffixes that match the 5-character prefix (typically 500-800 results).
- Compare the full hash against the returned suffixes locally.
- If a match is found, the password has been seen in a breach. Reject it.
// Check password against Have I Been Pwned API (Node.js)
const crypto = require('crypto');
async function isPasswordBreached(password) {
// Step 1: SHA-1 hash the password
const sha1 = crypto.createHash('sha1')
.update(password)
.digest('hex')
.toUpperCase();
// Step 2: Split into prefix (5 chars) and suffix
const prefix = sha1.substring(0, 5);
const suffix = sha1.substring(5);
// Step 3: Query the HIBP API with only the prefix
const response = await fetch(
`https://api.pwnedpasswords.com/range/${prefix}`,
{
headers: { 'Add-Padding': 'true' } // Prevents response-length analysis
}
);
const text = await response.text();
// Step 4: Check if our suffix appears in the results
const lines = text.split('\n');
for (const line of lines) {
const [hashSuffix, count] = line.split(':');
if (hashSuffix.trim() === suffix) {
return {
breached: true,
count: parseInt(count.trim(), 10), // How many times seen
};
}
}
return { breached: false, count: 0 };
}
// Usage in password validation
async function validatePassword(password, username) {
// Check length
if (password.length < 12) {
return { valid: false, reason: 'Password must be at least 12 characters.' };
}
// Check against username / email
if (password.toLowerCase().includes(username.toLowerCase())) {
return { valid: false, reason: 'Password must not contain your username.' };
}
// Check against breach database
const breach = await isPasswordBreached(password);
if (breach.breached) {
return {
valid: false,
reason: `This password has appeared in ${breach.count.toLocaleString()} data breaches. Please choose a different password.`,
};
}
return { valid: true };
}Privacy: Privacy guarantee: The API only sees a 5-character hash prefix that matches hundreds of different passwords. It never learns which specific password was checked. The full hash comparison happens entirely on your server.
As of 2025, the HIBP Passwords database contains over 900 million unique compromised passwords. If a user tries to set a password that appears in this list, it should be rejected with a clear explanation.
Alternatives to HIBP
10. Password Manager Recommendations
With passwords becoming longer and more unique (never reused across sites), password managers are no longer optional ā they are essential. A password manager generates, stores, and auto-fills strong unique passwords for every account.
Why password managers are critical:
- The average person has 100+ online accounts. No one can remember 100 unique, strong passwords.
- Password reuse is the #1 cause of credential-based breaches. A password manager eliminates reuse entirely.
- Password managers generate truly random passwords with maximum entropy, not human-predictable patterns.
- Auto-fill prevents phishing: a password manager will not fill credentials on a lookalike phishing domain.
| Feature | What to Look For |
|---|---|
| Zero-knowledge architecture | The service cannot read your passwords. Everything is encrypted locally with your master password. |
| Cross-platform sync | Works on all your devices (desktop, mobile, browser extension) with seamless syncing. |
| Breach monitoring | Alerts you when a stored password appears in a data breach. |
| Secure password generation | Built-in generator for random passwords and passphrases with configurable length and character sets. |
| Emergency access | Allows a trusted contact to access your vault if you are incapacitated. |
| Open source / audited | Code is publicly reviewable and has been independently audited by security firms. |
Tip: Master password tip: Your password manager's master password is the one password you MUST memorize. Use a 5-6 word Diceware passphrase (77+ bits of entropy). Write it down and store it in a physical safe until you have memorized it. Do NOT store it digitally.
For Developers: For developers building applications: Do not fight password managers. Ensure your login forms use standard HTML input types (<input type="password">) and autocomplete attributes (autocomplete="current-password" for login, autocomplete="new-password" for registration). Never disable paste on password fields.
11. Frequently Asked Questions
Is an 8-character password still acceptable in 2025?
Technically, NIST SP 800-63B sets 8 characters as the absolute minimum for user-chosen memorized secrets. However, most modern frameworks (PCI-DSS v4.0, Microsoft, Google) have moved to 12 characters as the minimum. An 8-character password has only about 52 bits of entropy even with full ASCII, which provides marginal security against offline attacks with modern hardware. We recommend 12 characters as the minimum for any new application in 2025.
Should I still require special characters in passwords?
No. NIST explicitly states that verifiers SHALL NOT impose composition rules requiring specific character types. These rules lead to predictable patterns ("Password1!") and add friction for users without meaningfully improving security. Instead, enforce a minimum length of 12+ characters and check against breach databases. Allow users to include any characters they want, but do not require specific types.
How often should users be forced to change their passwords?
Never, unless there is evidence of a compromise. NIST SP 800-63B states that verifiers SHALL NOT require periodic password changes. Research consistently shows that forced rotation leads to weaker passwords (predictable mutations) and security fatigue. Passwords should only be changed when there is a specific reason: a known breach, suspicious account activity, or the user voluntarily wants to change it.
What is the best password hashing algorithm to use in 2025?
Argon2id is the current gold standard, recommended by OWASP as the primary choice. Configure it with at least 19 MiB of memory (m=19456), 2 iterations (t=2), and 1 thread (p=1). If Argon2id is not available in your framework, use bcrypt with a cost factor of 12 or higher. Never use MD5, SHA-1, or SHA-256 for password storage ā these are general-purpose hash functions, not password hashing algorithms.
Are passkeys going to replace passwords entirely?
Passkeys (based on FIDO2/WebAuthn) are a significant advancement in authentication and are being adopted by major platforms (Apple, Google, Microsoft). They eliminate passwords entirely by using public-key cryptography tied to a device. However, passwords will coexist with passkeys for years to come. Many services still require password-based authentication as a fallback, and passkey support is not yet universal. For now, implement passkey support alongside strong password policies rather than replacing one with the other.
How do I convince my organization to adopt NIST guidelines?
Present the evidence: (1) NIST is the definitive authority on security standards in the US and is widely respected globally. (2) Research from Carnegie Mellon, Google, and Microsoft confirms that traditional password rules reduce security. (3) The old rules increase support costs (password resets are the #1 help desk call). (4) Major companies (Apple, Google, Microsoft) have already adopted these guidelines. (5) PCI-DSS v4.0 removed the mandatory rotation requirement when MFA is used, showing industry convergence. Frame it as a cost reduction and security improvement, not just a policy change.