Passwords, passkeys and MFA
Apply modern password rules, store passwords safely, and choose phishing-resistant sign-in.
- Apply NIST’s current password guidance
- Explain why passwords are stored as salted, slow hashes
- Compare MFA methods and why passkeys resist phishing
Password advice changed a lot. NIST SP 800-63B-4 (2025) says services should:
- require at least 15 characters when a password is the only factor (8 when it’s used with another factor), and allow at least 64;
- not impose composition rules like “one uppercase, one digit, one symbol”;
- not force periodic changes - only when there’s evidence of compromise;
- check every new password against a blocklist of common, expected and breached passwords;
- allow pasting, so people can use password managers.
Why? Composition rules produce Summer2026!, which follows every rule and is among the first things attackers try. Length and uniqueness matter far more. A passphrase of several randomly chosen words, like purple otter juggles maps at noon, is long and memorable - but attackers guess passphrases word by word too, so use five or more words (or let a password manager generate the password).
Try it
Password lab
Try the samples, then your own made-up passwords. Watch how length changes the guessing time, how a blocklist catches “clever” substitutions, and how much a slow hash slows an attacker down.
Don’t type a password you really use. Nothing leaves your browser, but it’s a good habit.
NIST would reject it: too short - at least 15 characters without MFA.
11 characters · pool of 95 possible characters per position
Average time to guess it by trying every combination
These are rough estimates. Real attackers try leaked passwords and common patterns first, which is why a blocklist matters more than symbols.
Storing passwords
A server must never store passwords in plain text - or encrypted, because anyone with the key could decrypt them all. Instead it stores a hash: a one-way fingerprint. At login it hashes what you typed and compares.
Two extra ingredients make stolen hashes hard to crack:
- A salt - random bytes, unique per user, stored next to the hash. Two people with the same password get different hashes, and precomputed tables become useless.
- A slow hash built for passwords - Argon2id, scrypt, bcrypt or PBKDF2 (OWASP Password Storage Cheat Sheet). General-purpose hashes like SHA-256 are designed to be fast, which helps attackers make billions of guesses a second.
import hashlib
for salt in ["a1b2", "c3d4"]:
print(salt, hashlib.sha256((salt + "correct-horse").encode()).hexdigest()[:16])a1b2 d1b83c8c2e90e14d c3d4 24441fbef1d18ac1
Multi-factor authentication
MFA combines different kinds of factor: something you know (password), have (phone, security key) or are (fingerprint). Not all MFA is equal:
| Method | Phishing-resistant? | Notes |
|---|---|---|
| SMS code | No | can be phished or stolen by SIM swapping |
| Authenticator app code | No | better than SMS, but a fake site can relay it |
| Push approval | No | vulnerable to MFA fatigue unless it uses number matching |
| Passkey / security key | Yes | public-key crypto bound to the real site’s domain |
A passkey stores a private key on your device. The site only keeps the public key, so there’s nothing reusable to steal from its database, and your browser refuses to use the key on a lookalike domain.
Key takeaways
Long, unique, blocklist-checked passwords; no composition rules or forced rotation.
Store passwords with a unique salt and a slow password hash (Argon2id, scrypt, bcrypt, PBKDF2).
Prefer phishing-resistant MFA: passkeys and security keys.
Lesson quiz
6 questions · pass with 5 correct · up to 50 XP
Passing this quiz completes the lesson and keeps your streak going. Questions you miss come back in review sessions later.
Practice: write Python
Write Python in the editor and run it against sample inputs. Python runs locally in your browser using a WebAssembly runtime.
Enforce NIST password rules
The first line is a comma-separated blocklist (lowercase). Each following line is yes PASSWORD or no PASSWORD - whether the password is used with MFA - and passwords may contain spaces.
Print reject: too short (LENGTH < MIN) if it is under 15 characters without MFA or 8 with MFA; otherwise reject: blocklisted if its lowercase form is on the blocklist; otherwise accept. No other rules!
- Five passwords
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Store and check salted, stretched hashes
Commands arrive one per line:
register USER SALT PASSWORD- store the hash and printUSER storedplus its first 16 hex digits.login USER PASSWORD- printUSER okif the password matches, elseUSER denied(also for unknown users).
Hash: start with the bytes of SALT + PASSWORD, then replace them with their SHA-256 digest 1000 times. Compare with hmac.compare_digest. (Real systems use Argon2id or similar - this shows the idea of a slow, salted hash.)
- Same password, different salts
Python runs in a sandboxed browser worker with a 60 second time limit. Its runtime loads from the Pyodide CDN; your code stays in this browser.
Questions about this lesson
Stuck? Ask. Figured something out? Share it. Explaining is one of the best ways to learn.
Loading posts…