Your country

Tools that support it use your country for local currency, number formats, units and paper size. Your choice is saved only in this browser.

Type a name or a two-letter code. Use the up and down arrow keys to move through the countries, Enter to choose one and Escape to close.

IT Support & Help Desk Fundamentals  Module 10 – Accounts, directories and access

Passwords, MFA and passkeys for support

Apply NIST SP 800-63B-4 password rules, rank MFA methods from SMS to passkeys, and help users enrol and recover without weakening accounts.

  • Beginner
  • 20 minutes
  • Examples run with Python 3.14.8 and Pyodide 314.0.7
  • By MySmartCoPilot
Free lesson, Pro answers: 20 minutes
Free: the whole lesson. With a pass: the model answers to its 2 interview questions.

What you will learn

  • Explain authentication, authorisation and the factor types
  • Apply NIST SP 800-63B-4 password rules and explain how they differ from older policies
  • Rank MFA methods from SMS codes to phishing-resistant passkeys and security keys
  • Recover a user's MFA access without weakening the account

Before you start

A user calls because their new 11-character password “Jm9!zPq#4Rb” was rejected even though it has uppercase, lowercase, digits and a symbol. The old policy said those were required; the current one asks for at least 15 characters when the password is the only factor. Password rules have changed, and a support technician who explains why earns more trust than one who just recites the error. Learn the rules NIST now publishes and the reasons behind them, rank MFA methods by what each one stops, and recover a user’s access without weakening the account.

Authentication proves identity; MFA mixes factor types

authentication: The process of proving who a user is, usually by providing one or more factors such as a password, a device, or a biometric. answers the question “who are you?” and authorisation: The process of deciding what an authenticated user may do: which resources they can access and which actions they can take. answers “what may you do?” A user signs in (authentication), and then the system decides whether they can read a file, approve a payment or change a setting (authorisation). Mixing the two is a common mistake: a locked-out user has an authentication problem, while a user who can sign in but cannot open a folder has an authorisation problem.

Authentication relies on factors, evidence a user provides to prove their identity. The three types are:

Factor type What it is Examples
Something you know A secret the user memorises Password, PIN, passphrase
Something you have A device or token the user possesses Phone, security key, smart card
Something you are A biometric the user presents Fingerprint, face, iris

Single-factor authentication uses one factor, usually a password. multi-factor authentication (MFA): Authentication that requires at least two independent factors from different types: something you know, something you have, or something you are. (MFA) requires at least two independent factors from different types. A password plus a code from an authenticator app is MFA because the password is something you know and the phone running the app is something you have. Two passwords are not MFA; they are still one factor type.

Two factors, not two steps

A site that asks for a password and then for the same password again is not using MFA. MFA means two different factor types, not two inputs of the same type.

Checkpoint

Check: Factor types and MFA

  1. Question 1 of 2 A user signs in with a password and then scans their fingerprint. Which factor types are involved?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: Something you know, and something you are

    Passwords are something you know, fingerprints are something you are, and the two together are MFA because they come from different factor types. The independence of the factors is what makes MFA stronger than two of the same type.

  2. Question 2 of 2 A site asks for a password and a PIN. Is this MFA?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: No, because both are something you know

    A password and a PIN are both secrets the user memorises, so both are something you know. MFA requires at least two independent factors from different types, such as a password plus a fingerprint or a password plus a phone.

NIST now asks for length and a blocklist, not complexity rules

The US National Institute of Standards and Technology publishes NIST SP 800-63B: A US federal guideline on digital identity authentication, published by NIST; the current version (SP 800-63B-4) requires longer passwords, blocklist checks, and no composition rules., a guideline many organisations follow. The current revision, SP 800-63B-4, differs sharply from the older rules that many policies and exams still describe.

Timeline · 8 events in order How password rules changed Walk through the policy shifts from legacy rules to NIST SP 800-63B-4. Each step drops a rule that hurt more than it helped or adds one that research supports.
  1. Legacy era

    Composition rules: uppercase, digit, symbol dropped

    Policies required at least one uppercase letter, one digit and one symbol. Users responded with predictable patterns like "Password1!" and wrote passwords down. The rules added friction without adding security.

  2. Legacy era

    Forced rotation every 90 days dropped

    Users had to change passwords every 60 to 90 days. Many made the smallest change the rule allowed, such as raising a trailing number by one, so the new password was as easy to guess as the old one.

  3. Legacy era

    Password hints and security questions dropped

    Knowledge-based hints like "mother's maiden name" were often guessable from public records or social media. Attackers used them to reset passwords without knowing the original.

  4. SP 800-63B rev 3

    Revision 3 advises against composition rules guidance

    Revision 3 said verifiers should not impose composition rules or make users change passwords on a calendar, and shall force a change when there is evidence of compromise. Length matters more than character variety.

  5. SP 800-63B rev 3

    A blocklist check and room for 64 characters guidance

    Revision 3 required new passwords to be compared with a list of commonly used, expected or compromised values, and asked verifiers to accept at least 64 characters so that long passphrases fit.

  6. SP 800-63B-4

    Revision 4 turns the advice into "shall not" guidance

    Revision 4 says verifiers shall not impose composition rules and shall not require periodic changes. A change is still forced on evidence that the password is compromised.

  7. SP 800-63B-4

    SP 800-63B-4 raises the minimum to 15 characters guidance

    A password used as the only factor now needs at least 15 characters; one used with a second factor keeps the minimum of 8. A passphrase of several words picked at random reaches 15 and is easier to remember than a short complex string.

  8. SP 800-63B-4

    The whole password meets the blocklist guidance

    Revision 4 keeps the blocklist and says the entire password is compared, not the words inside it. A long passphrase that contains a common word is accepted unless the whole phrase is on the list.

The timeline has 8 events, from Legacy era to SP 800-63B-4.

The main changes in summary:

Rule Legacy policy NIST SP 800-63B-4
Minimum length (single factor) 8 characters 15 characters
Minimum length (with MFA) 8 characters 8 characters
Maximum length Often 16 or 20 At least 64
Composition (uppercase, digit, symbol) Required Shall not be imposed
Periodic expiration Every 60–90 days Only on evidence of compromise
Blocklist check Rare Required (breached and common passwords)
Hints and security questions Common Shall not be used

The logic is straightforward. Composition rules lead to predictable patterns like “Password1!” because users satisfy the rules with minimal effort. Forced expiration invites the same shortcut, a trailing number raised by one at every change, so the guideline asks for a new password only when there is evidence the old one is compromised. Length matters more than complexity. “Jm9!zPq#4Rb” mixes every character type and still misses the 15-character minimum at 11. A randomly generated passphrase, such as “lantern cobalt mango drizzle”, reaches 28 characters that are easier to remember, and its strength comes from the random pick: four words from a list of 7,776 give 7,776⁴, about 3.7 × 10¹⁵ possible phrases. “Four random words” is a rule of thumb and not a guarantee of length: a generator picks again when the result is too short, or the user picks five words to clear 15 characters with room to spare. A phrase printed anywhere, this one included, is the kind of expected value a blocklist holds, so a real passphrase comes from a generator.

Not affiliated

MySmartCoPilot is not affiliated with CompTIA. The exam facts below come from CompTIA’s published exam objectives; the policy comparisons and examples in this lesson are this track’s own.

CompTIA’s A+ Core 2 (220-1202) exam objectives still list complexity and expiration, next to length, among the password considerations of objective 2.7, reflecting what many organisations still enforce. Learn both: what exams and older policies say, and what current NIST guidance requires and why. When a user asks why their complex password was rejected, a technician who can explain the shift—length over complexity, no forced rotation, blocklist checks—gives a better answer than one who only says “the system rejected it.”

NIST-aligned password checker Python · policy_check.py
#!/usr/bin/env python3
"""NIST SP 800-63B-4 aligned password acceptability checker.

SP 800-63B-4 requires:
- Single-factor passwords: at least 15 characters
- MFA passwords: at least 8 characters
- Verifiers should allow at least 64 characters
- No composition rules (no required symbols, digits, uppercase)
- No periodic changes except on evidence of compromise
- New passwords checked against a blocklist
- No hints or knowledge-based authentication questions

This checker applies the length and blocklist rules.
"""


def acceptable(password: str, context: str, blocklist: set[str]) -> tuple[bool, str]:
    """Check if a password meets NIST SP 800-63B-4 requirements.

    Args:
        password: The password to check (Unicode string).
        context: Either "single_factor" (>= 15 chars) or "mfa" (>= 8 chars).
        blocklist: A set of blocked passwords (checked case-insensitively).

    Returns:
        A tuple of (accepted: bool, reason: str).
    """
    # Trim leading and trailing whitespace (NIST allows this)
    trimmed = password.strip()

    # Count Unicode code points, not bytes
    length = len(trimmed)

    # Determine the minimum length by context
    if context == "single_factor":
        min_length = 15
    elif context == "mfa":
        min_length = 8
    else:
        return (False, f"Unknown context: {context}")

    # Check minimum length
    if length < min_length:
        return (False, f"Too short: {length} chars, need {min_length} for {context}")

    # Check blocklist (case-insensitive)
    if trimmed.lower() in blocklist:
        return (False, "Blocked: appears in the common-passwords list")

    # NIST: verifiers should allow at least 64 characters
    # We accept any length >= min_length; no upper limit enforced here
    return (True, f"Accepted: {length} chars for {context}")


# A small blocklist for demonstration (a real one has thousands)
BLOCKLIST = {
    "password", "123456", "qwerty", "letmein", "welcome",
    "admin", "monkey", "dragon", "sunshine", "princess",
    "iloveyou", "trustno1", "baseball", "football", "hello",
}

# Original sample passwords (not copied from any list)
SAMPLES = [
    # Single-factor tests
    ("shortpass12345", "single_factor"),      # 14 chars - too short
    ("blueskymorning7", "single_factor"),     # 15 chars - accepted
    ("thunderstormXYZabc", "single_factor"),  # 18 chars - accepted
    ("password", "single_factor"),            # 8 chars, blocklisted, too short
    ("verylongpasswordthatisabsolutelyaccepted", "single_factor"),  # 40 chars
    # MFA tests
    ("tiny123", "mfa"),                       # 7 chars - too short for MFA
    ("okaylength", "mfa"),                    # 10 chars - accepted for MFA
    ("letmein", "mfa"),                       # 7 chars, blocklisted
    ("briefmfa", "mfa"),                      # 8 chars - exactly minimum
    # Unicode length tests (code points, not bytes)
    ("cafénoir☕abc", "mfa"),                 # 12 code points - accepted
    ("日本語パスワード安全です", "single_factor"),  # 12 code points - too short
    ("日本語パスワード安全ですよ!", "single_factor"),  # 14 code points - too short
]


if __name__ == "__main__":
    print("NIST SP 800-63B-4 password policy check")
    print("=" * 50)
    print()

    for pwd, ctx in SAMPLES:
        accepted, reason = acceptable(pwd, ctx, BLOCKLIST)
        status = "ACCEPT" if accepted else "REJECT"
        # Show a truncated display for long passwords
        display = pwd if len(pwd) <= 25 else pwd[:22] + "..."
        print(f"{status:6} | {ctx:13} | {display:25} | {reason}")

Output

NIST SP 800-63B-4 password policy check
==================================================

REJECT | single_factor | shortpass12345            | Too short: 14 chars, need 15 for single_factor
ACCEPT | single_factor | blueskymorning7           | Accepted: 15 chars for single_factor
ACCEPT | single_factor | thunderstormXYZabc        | Accepted: 18 chars for single_factor
REJECT | single_factor | password                  | Too short: 8 chars, need 15 for single_factor
ACCEPT | single_factor | verylongpasswordthatis... | Accepted: 40 chars for single_factor
REJECT | mfa           | tiny123                   | Too short: 7 chars, need 8 for mfa
ACCEPT | mfa           | okaylength                | Accepted: 10 chars for mfa
REJECT | mfa           | letmein                   | Too short: 7 chars, need 8 for mfa
ACCEPT | mfa           | briefmfa                  | Accepted: 8 chars for mfa
ACCEPT | mfa           | cafénoir☕abc              | Accepted: 12 chars for mfa
REJECT | single_factor | 日本語パスワード安全です              | Too short: 12 chars, need 15 for single_factor
REJECT | single_factor | 日本語パスワード安全ですよ!            | Too short: 14 chars, need 15 for single_factor

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 policy_check.py

The checker applies two rules: minimum length by context (15 for single-factor, 8 for MFA) and a blocklist. It does not require uppercase, digits or symbols, and it counts Unicode code points, not bytes, so a passphrase in any language is measured fairly. The blocklist is compared with the whole password, never with a word inside it, and NIST’s examples of what the list may hold include context-specific words such as the service’s name and the user’s own username.

Pwned Password Checker Check a password against known breaches; only five characters of its hash are sent.

Checkpoint

Check: NIST password rules

  1. Question 1 of 2 Under NIST SP 800-63B-4, what is the minimum length for a password used as the only factor?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: 15 characters

    NIST SP 800-63B-4 requires passwords used as a single factor to be at least 15 characters, and passwords used with MFA to be at least 8. The longer minimum leaves room for passphrases of random words, which are easier to remember than a short complex string.

  2. Question 2 of 2 A policy requires at least one uppercase letter, one digit and one symbol. What does NIST SP 800-63B-4 say about this?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: Verifiers shall not impose composition rules

    NIST SP 800-63B-4 states that verifiers shall not impose composition rules. Research showed that such rules lead users to choose predictable patterns that satisfy the rules with minimal effort, reducing rather than increasing security.

Only origin-bound factors stop a convincing phishing site

Not all second factors offer the same protection. The table below ranks common MFA methods by phishing resistance, recovery options and user friction:

Interactive · answer and compare Which second factor fits the user and the risk? Answer three questions about the account you are protecting. The table shows which factors fit and why others fall short.
Is the account a high-value target for phishing, such as admin, finance or executive?
Does the organisation control the devices, or do users bring their own?
Is there budget for hardware keys?

Answer the questions above: the table then marks what fits your case and says why the rest does not.

Second factors compared for phishing resistance, recovery and user friction
Second factor Phishing resistance Recovery when lost User friction Per-user cost
SMS code How it works: code sent by text to a phone number Poor none: attacker can read the code if they control the link Good change the phone number, no hardware needed Good familiar to users, works on any phone Good any phone works; the sending service may bill per message
Authenticator app How it works: time-based code from an app like Google Authenticator Poor none: a fake page can relay the code within its 30-second window Mixed backup codes or re-enroll, secret is lost with the device Mixed user must open app, read code, type it in time Good no per-user cost beyond the authenticator app
Push notification How it works: approve or deny on a paired app Mixed some: user sees a prompt, but fatigue attacks succeed Mixed re-pair the app on a new device, needs identity proof Good one tap to approve, no code to type Mixed no hardware; depends on the identity provider's plan
Security key How it works: USB or NFC device, such as a YubiKey Good high: origin binding stops fake sites, no code to steal Mixed backup key or admin reset, hardware must be replaced Mixed user must carry and plug in a device Poor hardware is bought per user, which the other factors avoid
Passkey How it works: credential on a phone, computer or key, used after a fingerprint, face or PIN check Good high: origin bound, no shared secret to intercept Mixed synced passkeys recover via cloud, device-bound need backup Good biometric or PIN, no code to type or device to carry Good built into modern devices, no extra hardware
How the answers decide
  • “Is the account a high-value target for phishing, such as admin, finance or executive?” Yes, high-value target: rules out SMS code and Authenticator app. SMS codes and TOTP can be phished in real time. A high-value account needs a phishing-resistant factor: a security key or a passkey.
  • “Is the account a high-value target for phishing, such as admin, finance or executive?” No, standard user and “Does the organisation control the devices, or do users bring their own?” Bring your own device: adds a caveat to Security key. Users may forget or lose a key they carry themselves. Passkeys synced to a personal cloud or push notifications work on devices they already have.
  • “Is there budget for hardware keys?” No hardware budget: rules out Security key. Security keys add a per-user hardware cost. Passkeys use built-in hardware, and authenticator apps add no per-user cost.
  • “Does the organisation control the devices, or do users bring their own?” Managed devices and “Is there budget for hardware keys?” Yes, hardware budget exists: adds a caveat to SMS code, Authenticator app and Push notification. With managed devices and budget, security keys or device-bound passkeys give the strongest protection and central control.

SMS and voice codes

The weakest second factor. An attacker who controls the phone number—through a SIM swap: A social-engineering attack in which an attacker convinces or bribes a carrier employee to move a victim's phone number to a SIM the attacker controls, intercepting SMS codes. (convincing or bribing a carrier employee to move the number) or by intercepting the message—receives the code. CISA’s Scattered Spider advisory (AA23-320A) describes a group that used SIM swaps, and calls to help desks while posing as employees, to get past MFA.

Authenticator apps (TOTP)

An authenticator app generates a time-based code every 30 seconds using RFC 6238. The shared secret is held by the app and the server from enrolment onwards and never sent again. This is better than SMS because the shared secret does not travel with every sign-in, but the code can still be phished: an attacker who runs a fake sign-in page can relay the code to the real site within its 30-second window.

RFC 6238 TOTP test vectors Python · totp_demo.py
#!/usr/bin/env python3
"""RFC 6238 TOTP demonstration with test vectors.

TOTP (Time-based One-Time Password) generates a code from:
1. A shared secret known to authenticator and verifier
2. The current time, divided into steps (usually 30 seconds)

This demo reproduces the official test vectors from RFC 6238 Appendix B.
No secrets are transmitted; this is a local computation only.
"""

import hashlib
import hmac
import struct


def hotp(secret: bytes, counter: int, algorithm: str, digits: int = 8) -> str:
    """Generate HOTP code per RFC 4226.

    Args:
        secret: The shared secret as bytes.
        counter: The counter value (for TOTP, this is time / step).
        algorithm: Hash algorithm ("sha1", "sha256", or "sha512").
        digits: Number of digits in the output code (default 8).

    Returns:
        The HOTP code as a zero-padded string.
    """
    # Pack counter as 8-byte big-endian
    counter_bytes = struct.pack(">Q", counter)

    # Compute HMAC with the chosen algorithm
    if algorithm == "sha1":
        mac = hmac.new(secret, counter_bytes, hashlib.sha1).digest()
    elif algorithm == "sha256":
        mac = hmac.new(secret, counter_bytes, hashlib.sha256).digest()
    elif algorithm == "sha512":
        mac = hmac.new(secret, counter_bytes, hashlib.sha512).digest()
    else:
        raise ValueError(f"Unknown algorithm: {algorithm}")

    # Dynamic truncation: use last nibble as offset
    offset = mac[-1] & 0x0F

    # Extract 4 bytes starting at offset, mask top bit
    code_int = struct.unpack(">I", mac[offset : offset + 4])[0] & 0x7FFFFFFF

    # Reduce to the requested number of digits
    code = code_int % (10**digits)

    return str(code).zfill(digits)


def totp(secret: bytes, unix_time: int, step: int, algorithm: str, digits: int = 8) -> str:
    """Generate TOTP code per RFC 6238.

    Args:
        secret: The shared secret as bytes.
        unix_time: Unix timestamp (seconds since the Unix epoch).
        step: Time step in seconds (usually 30).
        algorithm: Hash algorithm ("sha1", "sha256", or "sha512").
        digits: Number of digits in the output code.

    Returns:
        The TOTP code as a zero-padded string.
    """
    counter = unix_time // step
    return hotp(secret, counter, algorithm, digits)


# RFC 6238 test vectors (Appendix B)
# These test secrets are the ASCII strings "12345678901234567890" repeated/truncated
# to 20, 32, or 64 bytes depending on the hash algorithm.
SECRET_SHA1 = b"12345678901234567890"  # 20 bytes for SHA-1
SECRET_SHA256 = b"12345678901234567890123456789012"  # 32 bytes for SHA-256
SECRET_SHA512 = b"1234567890123456789012345678901234567890123456789012345678901234"  # 64 bytes for SHA-512

# Test times from RFC 6238 Appendix B
TEST_VECTORS = [
    # (unix_time, expected_sha1, expected_sha256, expected_sha512)
    (59, "94287082", "46119246", "90693936"),
    (1111111109, "07081804", "68084774", "25091201"),
    (1111111111, "14050471", "67062674", "99943326"),
    (1234567890, "89005924", "91819424", "93441116"),
    (2000000000, "69279037", "90698825", "38618901"),
    (20000000000, "65353130", "77737706", "47863826"),
]

STEP = 30  # Standard 30-second step


if __name__ == "__main__":
    print("RFC 6238 TOTP test vectors (8-digit codes, 30-second step)")
    print("=" * 72)
    print()
    print(f"{'Time (Unix)':<14} {'SHA-1':<12} {'SHA-256':<12} {'SHA-512':<12} Status")
    print("-" * 72)

    all_pass = True
    for unix_time, exp_sha1, exp_sha256, exp_sha512 in TEST_VECTORS:
        got_sha1 = totp(SECRET_SHA1, unix_time, STEP, "sha1", 8)
        got_sha256 = totp(SECRET_SHA256, unix_time, STEP, "sha256", 8)
        got_sha512 = totp(SECRET_SHA512, unix_time, STEP, "sha512", 8)

        match_sha1 = got_sha1 == exp_sha1
        match_sha256 = got_sha256 == exp_sha256
        match_sha512 = got_sha512 == exp_sha512
        all_match = match_sha1 and match_sha256 and match_sha512
        all_pass = all_pass and all_match

        status = "PASS" if all_match else "FAIL"
        print(f"{unix_time:<14} {got_sha1:<12} {got_sha256:<12} {got_sha512:<12} {status}")

    print("-" * 72)
    print(f"\nOverall: {'All vectors passed' if all_pass else 'Some vectors failed'}")

Output

RFC 6238 TOTP test vectors (8-digit codes, 30-second step)
========================================================================

Time (Unix)    SHA-1        SHA-256      SHA-512      Status
------------------------------------------------------------------------
59             94287082     46119246     90693936     PASS
1111111109     07081804     68084774     25091201     PASS
1111111111     14050471     67062674     99943326     PASS
1234567890     89005924     91819424     93441116     PASS
2000000000     69279037     90698825     38618901     PASS
20000000000    65353130     77737706     47863826     PASS
------------------------------------------------------------------------

Overall: All vectors passed

Recorded with Python 3.14.8 on macOS 26 arm64. To run it yourself: mise exec python@3.14.8 -- python3 totp_demo.py

The demo computes the test vectors from RFC 6238 Appendix B using only the standard library. The same algorithm runs in Google Authenticator, Microsoft Authenticator and similar apps.

TOTP / HOTP Code Generator Watch a six-digit code change every 30 seconds from one shared key.

Push notifications with number matching

A push notification asks the user to approve the sign-in on their paired device. This is faster than typing a code and harder to phish because the user sees the request context (the app, the location). Without number matching, however, MFA fatigue: An attack that sends repeated MFA push notifications until the user approves one out of frustration; also called push bombing. Number matching defeats it. attacks succeed: an attacker triggers repeated prompts until the user taps “Approve” to stop them. Number matching—requiring the user to type into the app the number shown on the sign-in screen—defeats this: the number appears on the screen of whoever started the sign-in, so a user who did not start it never sees the number, and a reflex tap can no longer approve the attacker’s request.

Security keys and passkeys

FIDO2 security key: A physical device, such as a YubiKey, that authenticates using FIDO2 public-key cryptography; phishing-resistant because the credential is bound to the site origin. and passkey: A FIDO2 credential stored on a device or in a cloud keychain, used after the user verifies with a fingerprint, face or device PIN; phishing-resistant because it is bound to the site origin. are phishing-resistant MFA: An MFA method whose credential is cryptographically bound to the site origin, so a fake site cannot request it; examples include passkeys and FIDO2 security keys. because the credential is bound to the site’s origin. A fake site at “examp1e.com” cannot request a passkey for “example.com”; the browser refuses. No code travels that an attacker could intercept. CISA’s phishing-resistant MFA fact sheet recommends these for high-value accounts.

Interactive · stage by stage How a passkey sign-in works Step through a passkey sign-in. Watch how the server never sees the private key, and the credential is bound to the real site's origin.
How a passkey sign-in works, step 7 of 7. Showing User and device (signature created), Server (signature valid: authenticated). In focus: Server.User and devicesignature createdServersignature valid: authenticated

The drawing shows the whole scene; its 7 steps are listed below.

Every step as text
  1. User starts sign-in. The user enters their username or selects a saved passkey. No password is typed; the browser or OS will handle the credential.
  2. Server sends a challenge. The server generates a random challenge (a nonce) and sends it to the browser. The challenge is unique to this sign-in attempt, so a signature over it cannot be reused for another one.
  3. Browser checks the origin. The browser verifies that the request came from the real site. A phishing site at "examp1e.com" cannot trigger a passkey for "example.com" because the credential is bound to the origin.
  4. Device asks for verification. The device asks the user for verification with a fingerprint, face or device PIN. This proves the user is present and authorises use of the private key.
  5. Private key signs the challenge. The authenticator signs the challenge with the private key. The private key stays with the user's authenticator; only the signature travels to the server.
  6. Browser sends the response. The browser sends the signature, the client data (which names the origin and the challenge) and the credential ID back to the server. No secret is transmitted.
  7. Server verifies the signature. The server looks up the public key it stored at registration and verifies the signature against the challenge. If the signature is valid, the challenge is fresh, and the origin matches, sign-in succeeds.

The server stores only the public key. The private key stays with the user: on the device or security key, or in the cloud keychain that syncs it between the user’s own devices. A breach of the server therefore leaks nothing that lets an attacker sign in as the user. Synced passkeys make recovery easier, because a new phone signed in to the same keychain has them; device-bound passkeys (stored only on one security key or device) are harder to recover but cannot be copied to another device.

Checkpoint

Check: MFA method strength

  1. Question 1 of 2 Why is a passkey called phishing-resistant?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The credential is bound to the site origin, so a fake site cannot request it

    Passkeys are phishing-resistant because the credential is cryptographically bound to the site's origin. The browser checks the origin before it allows the credential to be used, so a convincing-looking fake site at a different domain cannot request the user's passkey.

  2. Question 2 of 2 An attacker runs a fake sign-in page that relays credentials to the real site. Which second factor can they defeat in real time?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: An authenticator-app code (TOTP)

    TOTP codes are valid for 30 seconds and have no binding to the site. An attacker who captures a code on a fake site can relay it to the real site before it expires. Passkeys and security keys are phishing-resistant because the credential is bound to the origin and cannot be used on a different domain.

Safe MFA recovery needs a channel the attacker cannot control

The help desk is itself an attack surface. Scattered Spider actors impersonated employees and called help desks to reset MFA, bypassing the second factor entirely. The fix is a verification step that an attacker cannot fake.

Enrolling MFA

When a user enrols MFA for the first time, they should:

  1. Sign in from a trusted device and network.
  2. Complete identity verification (a second channel like a video call, or verification by a manager).
  3. Register at least two methods so a lost phone does not lock them out.
  4. Store backup codes in a secure place, not a screenshot.

The technician’s job is to guide the user through the enrolment flow and confirm they have a backup method. Never enrol MFA on behalf of a user by reading their code aloud; that defeats the factor.

Recovering MFA

When a user loses access to their second factor, the recovery process must verify their identity through a channel the attacker cannot control. Put every step a procedure might use to one test: could an attacker who has researched the user do it too?

Recovery step Could a prepared attacker do it? Use it?
A backup code the user stored at enrolment No, the code is with the user Yes
A second registered phone or security key No, the device is with the user Yes
A video call with an ID check against the user’s record Hard: it needs the face and the document Yes
The manager confirms in person or on a number from the directory No, the attacker does not pick the channel Yes
A reset link sent to an email address the caller gives Yes, the caller can give an address they control No
Answers about the user: employee number, manager’s name, phone digits Yes, all of it can be found No
A caller who sounds sure, urgent or senior Yes, that is the usual approach No

Every “No” row fails for the same reason: a step that an attacker could also complete is not verification, however convincing the caller sounds.

Resetting MFA over the phone

Wrong: “I’ll reset your authenticator app; what’s the code on your screen?” Right: “I’ll send a reset link to your backup email, and your manager will confirm the request before we process it.” The wrong version gives the attacker exactly what they need.

Password managers and passphrases

A password manager stores long, unique passwords so users do not have to memorise them. The one password a user still has to remember is what opens the vault, which is where a passphrase of several random words fits: long enough for the 15-character rule and easy to type.

Passphrase Generator (Diceware) Make a passphrase of random words to open a password manager's vault. Password Strength Checker Compare how long a short complex password and a four-word passphrase would last against guessing.

When a user asks which password manager to use, the answer is: any reputable one is better than none. The goal is long, unique passwords for every site, stored encrypted, and opened with one strong passphrase or with a passkey.

Checkpoint

Check: Defensive help-desk practices

  1. Question 1 of 2 A caller says they lost their phone and need their MFA reset. What is the first thing to verify?

    Choose one answer.

    Show the answer: Question 1 of 2

    Answer: The caller's identity through a channel the attacker cannot control

    The help desk is an attack surface. Scattered Spider actors called help desks to reset MFA by impersonating employees. Verification must use a channel the attacker cannot control: a backup code, a separate device, a video call with ID, or a manager confirming in person or through a separate channel.

  2. Question 2 of 2 At MFA enrolment, why should the user register more than one method?

    Choose one answer.

    Show the answer: Question 2 of 2

    Answer: So a lost phone does not lock them out

    Registering at least two MFA methods means a lost phone does not lock the user out. A backup code, a second phone, or a security key can restore access when the primary device is unavailable.

Practise: decide which passwords a policy should accept

The starter is a legacy policy: eight characters with an uppercase letter, a digit and a symbol, so it accepts “Jm9!zPq#4Rb” and refuses a long lowercase passphrase. Replace it with the rules of this lesson, plus the context-specific rule from the NIST section: refuse a password that is the user’s own username, compared whole and without regard to case, never searched for inside a longer password. The sample tests fail on the legacy starter and pass once every rule holds.

Exercise · Easy · Python

NIST-aligned password acceptability checker

The starter acceptable(password, context, blocklist, username="") in password_check.py is a legacy policy: at least 8 characters with an uppercase letter, a digit and a symbol. Replace it with a check that meets NIST SP 800-63B-4.

The function receives:

  • password: a Unicode string (it may contain leading or trailing whitespace, which should be trimmed)
  • context: either "single_factor" (minimum 15 characters) or "mfa" (minimum 8 characters)
  • blocklist: a set of lowercase blocked passwords
  • username: the user's own username, when the caller knows it (an empty string otherwise)

The function returns a tuple (accepted, reason):

  • accepted is True if the password is acceptable, False otherwise
  • reason is a short string explaining the decision

Rules to apply:

  1. Trim leading and trailing whitespace from the password before checking.
  2. Count Unicode code points (characters), not bytes. The emoji "☕" is 1 character; "café" is 4.
  3. If the context is "single_factor", the minimum length is 15 characters.
  4. If the context is "mfa", the minimum length is 8 characters.
  5. Refuse any other context.
  6. Compare the whole trimmed, lowercased password with the blocklist. If it matches an entry, refuse it.
  7. Refuse a password that equals the username, ignoring case. Compare the whole password: a longer password that only contains the username is not refused by this rule.
  8. Do not impose composition rules (no requirement for uppercase, digits or symbols).

The sample tests include passwords at the exact minimum lengths, a short complex password, Unicode passphrases, the username in another case and an unknown context.

Starter code · password_check.py

# Check whether a password meets NIST SP 800-63B-4 requirements.
# This starter is the legacy policy the exercise replaces: it wants composition, not length.


def acceptable(password, context, blocklist, username=""):
    """Check if a password is acceptable for the given context.

    Args:
        password: The password to check (Unicode string).
        context: Either "single_factor" (>= 15 chars) or "mfa" (>= 8 chars).
        blocklist: A set of blocked passwords, in lowercase.
        username: The user's own username, if known; a password equal to it is refused.

    Returns:
        A tuple of (accepted: bool, reason: str).
    """
    has_upper = any(c.isupper() for c in password)
    has_digit = any(c.isdigit() for c in password)
    has_symbol = any(not c.isalnum() for c in password)
    if len(password) < 8:
        return (False, "Too short: the legacy policy wants 8 characters")
    if not (has_upper and has_digit and has_symbol):
        return (False, "Rejected: wants an uppercase letter, a digit and a symbol")
    return (True, "Accepted by the legacy policy")
The sample tests · test_password_check.py
from password_check import acceptable


BLOCKLIST = {"password", "letmein", "welcome", "admin", "qwerty"}
USER = "Asha.Kumar"


def test_single_factor_minimum():
    """single-factor passwords must be at least 15 characters"""
    result, _ = acceptable("shortpassword1", "single_factor", BLOCKLIST, USER)
    assert result is False, "14 characters is too short for single_factor"

    result, _ = acceptable("fifteencharacte", "single_factor", BLOCKLIST, USER)
    assert result is True, "exactly 15 characters is acceptable for single_factor"


def test_mfa_minimum():
    """MFA passwords must be at least 8 characters"""
    result, _ = acceptable("short12", "mfa", BLOCKLIST, USER)
    assert result is False, "7 characters is too short for mfa"

    result, _ = acceptable("eightchr", "mfa", BLOCKLIST, USER)
    assert result is True, "exactly 8 characters is acceptable for mfa"


def test_composition_is_not_enough():
    """a short complex password fails the single-factor length rule"""
    result, _ = acceptable("Jm9!zPq#4Rb", "single_factor", BLOCKLIST, USER)
    assert result is False, "11 characters is too short for single_factor"


def test_unicode_length():
    """length is measured in code points, not bytes"""
    # 8 code points, 11 bytes in UTF-8
    result, _ = acceptable("café☕abc", "mfa", BLOCKLIST, USER)
    assert result is True, "8 Unicode code points is acceptable for mfa"

    japanese = "日本語パスワード安全ですよ!"  # 14 code points, 42 bytes in UTF-8
    result, _ = acceptable(japanese, "single_factor", BLOCKLIST, USER)
    assert result is False, "14 code points is too short for single_factor"


def test_blocklist_whole_password_any_case():
    """the whole lowercased password is compared with the blocklist"""
    result, _ = acceptable("PASSWORD", "mfa", BLOCKLIST, USER)
    assert result is False, "PASSWORD lowercased is on the blocklist"

    result, _ = acceptable("LETMEIN!", "mfa", BLOCKLIST, USER)
    assert result is True, "letmein! is not an entry of the blocklist"


def test_username_is_refused_whole_not_as_a_substring():
    """a password equal to the username is refused; one that only contains it is not"""
    result, _ = acceptable("asha.KUMAR", "mfa", BLOCKLIST, USER)
    assert result is False, "the password is the username in another case"

    result, _ = acceptable("asha.kumar runs on sunday", "mfa", BLOCKLIST, USER)
    assert result is True, "a password that only contains the username is allowed"


def test_unknown_context_is_refused():
    """only the two contexts of the rules are accepted"""
    result, _ = acceptable("a long and unusual passphrase", "mfa", BLOCKLIST, USER)
    assert result is True, "29 characters is acceptable for mfa"

    result, _ = acceptable("a long and unusual passphrase", "sms", BLOCKLIST, USER)
    assert result is False, "an unknown context such as sms is refused"


def test_whitespace_trimmed():
    """leading and trailing whitespace is trimmed before checking"""
    result, _ = acceptable("  short1  ", "mfa", BLOCKLIST, USER)
    assert result is False, "trimmed length of 6 ('short1') is too short for mfa"

    result, _ = acceptable("  fifteencharacter  ", "single_factor", BLOCKLIST, USER)
    assert result is True, "trimmed length of 16 is acceptable"
A hint

Delete the composition checks first: none of the rules asks for them. Then trim the password with password.strip() and use len() to count characters; in Python, len() on a string returns the number of Unicode code points, which is what the rules require. Compare the length against 15 or 8 depending on the context, and compare the whole lowercased password with == or in blocklist, never with a search inside it.

The sample tests run on this device, in your browser (Pyodide): nothing is sent to mysmartcopilot.com. The first run downloads Python (about 13.5 MB), which is kept for the next runs. A check in your browser is feedback for you, not proof that the code is right for every input.

Practice that adapts to you

Practise this lesson

9 questions about 4 ideas of this lesson. Each answer is explained at once, and what you get right is kept in this browser.

  1. Question 1 of 9 A user can sign in but cannot open a shared folder. Is this an authentication problem or an authorisation problem?

    Choose one answer.

    Show the answer: Question 1 of 9

    Answer: Authorisation

    Authentication answers "who are you?" and authorisation answers "what may you do?" The user signed in (authentication), and then the system denied access to the folder (authorisation). A support technician who mixes the two will troubleshoot the wrong layer.

  2. Question 2 of 9 Why does NIST require new passwords to be checked against a blocklist?

    Choose one answer.

    Show the answer: Question 2 of 9

    Answer: A password that appears in a breach is already in attacker dictionaries

    A password that has appeared in a public breach is already in attacker dictionaries. NIST asks for a blocklist large enough to stop the passwords attackers are likely to guess before the sign-in attempt limit is reached.

  3. Question 3 of 9 What is a SIM swap attack?

    Choose one answer.

    Show the answer: Question 3 of 9

    Answer: An attacker convinces a carrier to move the victim's phone number to a SIM they control

    A SIM swap is a social-engineering attack on the carrier. The attacker convinces or bribes a carrier employee to move the victim's phone number to a SIM they control. They then receive all SMS codes sent to that number.

  4. Question 4 of 9 How does number matching defeat MFA fatigue attacks?

    Choose one answer.

    Show the answer: Question 4 of 9

    Answer: The user must type into the app a number shown only on the screen where the sign-in started

    MFA fatigue attacks send repeated push prompts until the user approves one out of frustration. Number matching shows a number on the screen where the sign-in started and asks the user to type it into the app. In a fatigue attack that screen belongs to the attacker, so the user receiving the prompts has nothing to type and blind approval fails.

  5. Question 5 of 9 What happens if the server storing passkey credentials is breached?

    Choose one answer.

    Show the answer: Question 5 of 9

    Answer: The attacker gets only public keys, which cannot impersonate users

    Passkeys use public-key cryptography. The user's authenticator holds the private key; the server holds only the public key. A server breach leaks public keys, which cannot sign challenges, so the attacker cannot impersonate users.

  6. Question 6 of 9 A bank sends a one-time code by SMS to the same phone that holds the banking app the user signs in from. What has the design lost?

    Choose one answer.

    Show the answer: Question 6 of 9

    Answer: The independence of the two factors, because one stolen phone yields both

    MFA works because the factors fail independently: losing a memorised password does not hand over a phone. A code sent to the same phone the user signs in from collapses that independence, so one stolen phone with its screen already signed in is enough. This is why a help desk asks where a user's factors live, not only how many they have.

  7. Question 7 of 9 Under NIST SP 800-63B-4, when should a user be made to change their password?

    Choose one answer.

    Show the answer: Question 7 of 9

    Answer: When there is evidence the password is compromised

    Forced expiration made users change a working password on a schedule, and they responded with predictable small edits. SP 800-63B-4 asks instead for a change when there is evidence of compromise, which is when a change actually helps.

  8. Question 8 of 9 During an enrolment call, a technician asks the user to read out the code from their authenticator app so the technician can finish the setup. What is wrong with this?

    Choose one answer.

    Show the answer: Question 8 of 9

    Answer: The code is the second factor, and reading it out hands it to whoever is listening

    The point of a second factor is that only the user holds it. A technician who takes the code over the phone both breaks that and trains the user to read codes to callers, which is exactly what a social engineer asks for. The technician's job at enrolment is to guide and to confirm a backup method exists.

  9. Question 9 of 9 You are writing the MFA recovery procedure for a help desk. Which test tells you a step is strong enough?

    Choose one answer.

    Show the answer: Question 9 of 9

    Answer: Ask whether an attacker who knows everything public about the user could complete the step

    A recovery step is only as strong as the channel it depends on. Asking what an attacker who has done their research could also do rules out security questions, caller ID and shared knowledge, and leaves backup codes stored apart, a second registered device, an identity check against the record, and confirmation from a person who recognises the user.

Interview questions on identity

Interviewers for support roles often start with the call from the opening and then move to work that changes many accounts at once. The warm-up below is that first call. The two cases after it ask you to plan rather than recall: retiring SMS codes for twenty people with mixed phones, and giving two hundred new joiners two independent methods on their first day.

Warm-up

A user asks why their new password was rejected even though it has uppercase, lowercase, digits and a symbol. What do you tell them?

Current password guidance (NIST SP 800-63B-4) forbids composition rules such as requiring uppercase letters, digits and symbols. What it asks for instead is length, at least 15 characters for a password used without MFA, and a check of the whole password against a blocklist of common and breached passwords. A short complex password like “Jm9!zPq#4Rb” is rejected because its 11 characters are under that minimum; the mix of character types does not make up for the missing length. A randomly generated passphrase from a password manager — five short words, or four longer ones — clears the minimum and is easier to remember than a short complex string. I would explain the reason behind the rule, that length matters more than complexity, and suggest a generated passphrase or a password manager.

Model answers open with any pass: ₹79 for 1 week ($2.99), one payment that never renews.

  1. Mid to senior

    Your company protects every account with SMS codes. Security cites SIM swaps and asks you to retire SMS for the twenty people who handle finance, admin or production access. The twenty have mixed phones: eight iPhones, nine Androids and three basic phones without apps. Plan the switch so no account ever drops below SMS during it.

    Model answer, Pro. Model answers open with any pass; prices are in the notice on this page. First step and follow-ups

  2. Fresher to mid

    You are rolling out passkeys to two hundred new joiners next month. HR asks for the fastest enrolment that still "protects the account". Design the day-one flow that leaves every new joiner with two sign-in methods that cannot be lost together, and no backup secret stored on the laptop being set up.

    Model answer, Pro. First step and follow-ups

Flashcards · 7 cards

Recall it, then check

Say the answer to yourself before you look: recalling it is what makes it stick.

  1. How does authentication differ from authorisation?

    Authentication proves who the user is. Authorisation decides what that user may reach and what they may do.

  2. What makes a sign-in multi-factor?

    At least two independent factors of different types: something you know, something you have and something you are.

  3. What does NIST SP 800-63B-4 ask of a password used without MFA?

    At least 15 characters and a check of the whole password against a blocklist of common and breached passwords. It forbids composition rules and forced rotation.

  4. A new password with upper and lower case, digits and a symbol was rejected. Why can that be right?

    Current guidance values length over mixed characters: an 11-character complex password is under the 15-character minimum for a password used without MFA, and the mix does not make up for it. A long, randomly generated passphrase is the better answer.

  5. How do SMS codes, TOTP codes and passkeys compare as second factors?

    SMS codes are the weakest, because of SIM swaps. TOTP codes are better but can be phished within their time window. Passkeys and security keys stand up to phishing: each credential works only for the origin it was made for.

  6. What is MFA fatigue, and what stops it?

    A flood of push prompts sent until the user accepts one out of frustration, also called push bombing. Number matching stops it.

  7. What makes a help-desk MFA recovery safe?

    Checking the person's identity through a channel the attacker cannot control. A code the caller reads aloud, or a reset link sent to a mailbox that may be taken over, verifies nothing.

Key takeaways

  • Authentication proves identity; authorisation grants permissions. MFA combines at least two independent factors from different types: something you know, have or are.
  • NIST SP 800-63B-4 requires 15-character passwords for single-factor authentication, blocklist checks, and no composition rules or forced rotation. Learn both current guidance and older exam expectations.
  • SMS codes are the weakest second factor (SIM swaps). TOTP codes are better but phishable within their window. Passkeys and security keys are phishing-resistant because the credential is bound to the origin.
  • Help-desk recovery must verify identity through a channel an attacker cannot control. A code read aloud or a reset link to a compromised email is not verification.

Terms in this lesson

authentication
The process of proving who a user is, usually by providing one or more factors such as a password, a device, or a biometric.
authorisation
The process of deciding what an authenticated user may do: which resources they can access and which actions they can take.
MFA fatigue
An attack that sends repeated MFA push notifications until the user approves one out of frustration; also called push bombing. Number matching defeats it.
multi-factor authentication (MFA)
Authentication that requires at least two independent factors from different types: something you know, something you have, or something you are.
NIST SP 800-63B
A US federal guideline on digital identity authentication, published by NIST; the current version (SP 800-63B-4) requires longer passwords, blocklist checks, and no composition rules.
passkey
A FIDO2 credential stored on a device or in a cloud keychain, used after the user verifies with a fingerprint, face or device PIN; phishing-resistant because it is bound to the site origin.
phishing-resistant MFA
An MFA method whose credential is cryptographically bound to the site origin, so a fake site cannot request it; examples include passkeys and FIDO2 security keys.
security key
A physical device, such as a YubiKey, that authenticates using FIDO2 public-key cryptography; phishing-resistant because the credential is bound to the site origin.
SIM swap
A social-engineering attack in which an attacker convinces or bribes a carrier employee to move a victim's phone number to a SIM the attacker controls, intercepting SMS codes.

References

Related tools

Report a problem with this lesson

Quick answers and tool search

Type to search tools or to get a quick answer, for example 18% of 2500. Use the up and down arrow keys to move through the results, Enter to choose, and Escape to close.