Factors and methods: a recap

Multi-factor authentication (MFA) combines authentication factors of different kinds — something you know, something you have, something you are. Both terms, and the basics of authenticator codes (time-based one-time passwords, TOTP) and passkeys, are explained in Passwords and Authentication; this page goes deeper into what an identity team chooses, rolls out and supports.

A useful distinction: the factor is the kind of proof, the method is the concrete technology. "Something you have" can be a phone receiving an SMS, a phone running an authenticator app, a FIDO2 security key or a smart card — and these differ enormously in how well they resist attackers. In Microsoft Entra ID, which methods users may register is set in the Authentication methods policy. Since 30 September 2025 the older per-feature MFA and self-service password reset (SSPR) method settings can no longer be used to manage methods.

Methods ranked from weak to strong

Method Can a real-time phishing site use it? Main weakness Where it fits
SMS or voice call code Yes SIM swapping, interception; NIST lists it as a "restricted" authenticator Last-resort fallback only
Email one-time code Yes The mailbox is often protected by the same password Low-risk consumer recovery
Authenticator app code (TOTP) Yes The user types the code wherever they are asked to Better than SMS; not phishing-resistant
Push notification, approve/deny Yes MFA fatigue: approving a prompt the user did not start Avoid without number matching
Push with number matching and context Yes (a relay site shows the number too) Stops blind approvals, not relay phishing Good baseline for most users
FIDO2 security key No Can be lost; users need a spare or a recovery path Administrators, high-risk roles, shared workstations
Passkey (synced or device-bound) No Synced passkeys are only as safe as the account they sync through Everyone, as the default goal
Windows Hello for Business No Bound to one device; each device needs enrollment Managed Windows computers
Certificate-based authentication (smart card) No Needs a public key infrastructure to run Government, organizations with an existing PKI

The dividing line in the middle of the table matters more than the order within each half. Everything above it produces something the user can hand over — a code, an approval — to whoever asks. Below it the user cannot hand over anything useful, because the proof is calculated by a device for one specific website.

MFA fatigue and number matching

MFA fatigue (push bombing, MITRE ATT&CK T1621, "multi-factor authentication request generation") is an attack on push-based MFA: an attacker who already has the password signs in again and again, so the victim receives prompt after prompt — often at night, sometimes combined with a message or call from "IT support" — until they approve one to make it stop. It is widely cited from the Uber breach of September 2022: according to Uber and press reports, an attacker used a contractor's stolen password, sent repeated push requests and contacted the contractor over WhatsApp posing as IT, until one request was accepted. Uber attributed the attack to the Lapsus$ group. See also Social Engineering and Phishing.

Number matching is the main countermeasure: the sign-in screen shows a number, and the user has to type that number into the authenticator app to approve. A user who did not start a sign-in has no number to type, so blind approval becomes impossible. Microsoft Authenticator has required number matching for all push notifications since May 2023. Administrators can also turn on additional context — the application and the approximate location of the sign-in — which is off by default. Number matching does not stop a relay phishing site, which simply shows the user the number it received from the real sign-in page.

Detect and respond as well as prevent:

  • Teach one rule: a prompt you did not start is denied and reported. Give users a "report fraud" option in the app.
  • Alert on many denied or unanswered MFA prompts for one account in a short time: the attacker already has that account's password, so reset it.
  • Treat help desk requests to "reset my MFA" as high risk; verify the caller through a second channel.

Phishing-resistant MFA

Phishing-resistant MFA is multi-factor authentication whose result cannot be captured on a fake site and replayed at the real one, because the cryptographic proof is bound to the real site's origin (or to a channel the attacker does not control). FIDO2 and WebAuthn — security keys, passkeys, Windows Hello for Business — and certificate-based authentication with smart cards are the phishing-resistant methods in use today. CISA (the United States Cybersecurity and Infrastructure Security Agency) published a fact sheet in October 2022 that calls FIDO/WebAuthn the only widely available phishing-resistant authentication, names smart-card style public key infrastructure (PKI) as the other form, and recommends number matching only as an interim step.

Why a code can be phished

A TOTP code is calculated from a shared secret and the current time (RFC 6238). The example checks an implementation against the official 8-digit test vectors from the RFC, then shows the problem: a verifier accepts the code from whoever sends it, within the allowed time window.

import hashlib
import hmac
import struct


def totp(secret, unix_time, digest=hashlib.sha1, digits=8, step=30):
    """Time-based one-time password, RFC 6238 (HOTP of the 30-second step number)."""
    counter = struct.pack(">Q", unix_time // step)
    mac = hmac.new(secret, counter, digest).digest()
    offset = mac[-1] & 0x0F
    number = struct.unpack(">I", mac[offset:offset + 4])[0] & 0x7FFFFFFF
    return str(number % 10**digits).zfill(digits)


# Test vectors from RFC 6238, Appendix B: each hash has its own seed.
SEEDS = {
    "SHA1": (b"12345678901234567890", hashlib.sha1),
    "SHA256": (b"12345678901234567890123456789012", hashlib.sha256),
    "SHA512": (b"1234567890" * 6 + b"1234", hashlib.sha512),
}
EXPECTED = {
    (59, "SHA1"): "94287082", (59, "SHA256"): "46119246", (59, "SHA512"): "90693936",
    (1111111109, "SHA1"): "07081804", (1111111109, "SHA256"): "68084774",
    (1111111109, "SHA512"): "25091201",
}

for (t, name), wanted in EXPECTED.items():
    seed, digest = SEEDS[name]
    code = totp(seed, t, digest)
    print(f"T={t:<11}{name:<7}{code}  {'matches RFC' if code == wanted else 'WRONG'}")


# A verifier accepts the current step and one step either side, for clock drift.
def verify(secret, code, now):
    return any(totp(secret, now + drift, digits=6) == code for drift in (-30, 0, 30))


secret = SEEDS["SHA1"][0]
typed_on_fake_site = totp(secret, 1790000000, digits=6)   # the user types the code
relayed_by_attacker = 1790000000 + 12                     # the kit replays it 12 s later
print()
print("code typed on the phishing page:", typed_on_fake_site)
print("accepted from the attacker:", verify(secret, typed_on_fake_site, relayed_by_attacker))
T=59         SHA1   94287082  matches RFC
T=59         SHA256 46119246  matches RFC
T=59         SHA512 90693936  matches RFC
T=1111111109 SHA1   07081804  matches RFC
T=1111111109 SHA256 68084774  matches RFC
T=1111111109 SHA512 25091201  matches RFC

code typed on the phishing page: 144003
accepted from the attacker: True

Nothing in the calculation involves the website's name. The verifier sees a correct code arriving within its window and cannot tell that it came from an adversary-in-the-middle phishing kit rather than the user. The same holds for SMS codes and, with an extra step, for push with number matching. (Most apps use six digits and SHA-1; the RFC's test vectors use eight.)

Origin binding

Phishing-resistant methods remove the human from the decision "which site is this?". With WebAuthn the browser tells the authenticator which origin (scheme and domain) is asking, and puts that origin into the data that gets signed. A credential created for login.example.com is simply not offered to login.example.net, however convincing that page looks.

Origin binding. On the real site, a browser at login.example.com asks the authenticator, which has a key for that origin, so it returns a signed response that the identity provider accepts. On a lookalike site, a browser at login.example.net asks the authenticator, which has no key for that origin, so there is no usable response for the phishing proxy to relay. Real site Browser at login.example.com Authenticator: key for this origin? yes Signed response IdP accepts it Phishing site Browser at login.example.net Authenticator: key for this origin? no No usable response nothing to relay The browser, not the user, tells the authenticator which site is asking.
The user may be fooled by a lookalike domain; the browser and the authenticator are not.

FIDO2 and WebAuthn

FIDO2 is the FIDO Alliance's set of standards for public-key authentication without shared secrets. It has two parts: WebAuthn between the website and the browser, and the Client to Authenticator Protocol (CTAP) between the browser or operating system and an external authenticator such as a USB, NFC (near-field communication) or Bluetooth security key.

WebAuthn (Web Authentication) is the World Wide Web Consortium (W3C) standard browser API that lets a website register and use public-key credentials. Its Level 3 version became a W3C Recommendation on 25 August 2026. It works in two ceremonies:

  1. Registration: the website (the relying party) sends a random challenge and its identifier, the relying party ID — normally its domain. The authenticator creates a new key pair for that relying party, keeps the private key, and returns the public key, a credential ID and, optionally, an attestation that says which make and model of authenticator created it. The site stores the public key.
  2. Authentication: the site sends a fresh challenge. The browser adds the origin, the authenticator checks that it has a credential for that relying party, verifies the user locally (PIN, fingerprint or face) and signs the challenge and origin with the private key. The site verifies the signature with the stored public key.

Three properties follow: the private key never leaves the authenticator, the server holds nothing a breach could reuse, and the PIN or fingerprint is checked locally and never sent anywhere. The fingerprint is not the credential; it only unlocks the key on that device.

Synced and device-bound passkeys

A passkey is a FIDO2 credential used instead of a password (see passkeys). Organizations care about where it lives:

  • Synced passkeys are copied, end-to-end encrypted, between a person's devices through their platform account or password manager. Losing a phone does not lose the passkey — convenient, but its security now also depends on that sync account. Synced passkeys cannot prove their make and model (attestation).
  • Device-bound passkeys stay in one piece of hardware — a FIDO2 security key, or Microsoft Authenticator on a specific phone — and cannot be exported. They can be attested, so an organization can allow only approved security key models.

NIST SP 800-63B-4 (August 2025) accepts syncable authenticators at authentication assurance level 2 (AAL2), but says they shall not be used at AAL3, the highest level, which requires a non-exportable key. A common policy follows from that: synced passkeys for most staff, device-bound keys for administrators. Microsoft Entra ID supports both kinds in all editions, including Free, and its passkey profiles let you require device-bound keys, attestation or specific authenticator models for a group of users. Microsoft describes synced passkeys as phishing-resistant but, because they cannot be attested, with the same security posture as other unattested authenticators.

Windows Hello for Business

Windows Hello for Business (WHfB) replaces the Windows password on managed computers with a key pair (or a certificate) bound to the device: the private key is protected by the device's Trusted Platform Module (TPM), and the user unlocks it with a PIN, fingerprint or face. Entra ID or AD DS stores only the public key.

The PIN confuses people, so it is worth stating plainly: a WHfB PIN is not a short password. It never leaves the device, it is not known to the domain, and it only unlocks the key in this one TPM. Someone who learns it cannot use it from another computer, and the TPM limits guessing on the device itself. That is why a six-digit PIN here is stronger than a long password that works everywhere.

Because the key is bound to the device, WHfB is phishing-resistant and counts as MFA by itself: possession of the device plus the PIN or biometric. Microsoft documents several deployment models (key-based, certificate-based and "cloud Kerberos trust", which also gives access to on-premises resources); which one fits depends on whether the computers are Entra joined or hybrid joined and on what on-premises resources they reach. Users need to enroll on each device they use, which makes it a poor fit for shared or frequently swapped computers — use FIDO2 security keys there.

Going passwordless

Passwordless authentication is sign-in in which the user never types a password: a passkey, Windows Hello for Business, a FIDO2 security key or a smart card proves possession of a private key, unlocked locally by a PIN or biometric. The password may still exist in the directory for a while; the goal is that it is never used, and eventually that nobody knows it.

A rollout that works:

  1. Start with administrators and other high-risk roles: device-bound security keys, two per person.
  2. Enable the methods in the Authentication methods policy, group by group, and let users register a passkey while their old MFA still works.
  3. Require phishing-resistant MFA with conditional access authentication strengths, first for admins and sensitive applications (see Conditional Access and Zero Trust).
  4. Remove weaker methods such as SMS for groups that have moved, so attackers cannot fall back to them.

Recovery: lost devices and new phones

Recovery is where passwordless projects succeed or fail, and where attackers look first. A user who loses the only device with their passkey cannot sign in to register a new one. Plan for it:

  • Everyone registers at least two methods — for example a passkey on the phone and Windows Hello on the laptop, or two security keys.
  • A Temporary Access Pass (TAP) in Entra ID is a time-limited passcode that an administrator issues so a user can sign in once (or for a short period) to register new passwordless methods. It is also how new employees set up their first passkey without ever having a password.
  • The TAP is only as strong as the identity check before it is issued. A caller who claims to have lost their phone is exactly what an attacker would say: verify through a callback to a known number, a manager's confirmation or in person, as described in Account recovery.
  • When a device is lost, remove its registered methods and revoke the user's sessions, not only the device.

Passwords that are still needed

Passwords will be around for years, so make the remaining ones good. The United States National Institute of Standards and Technology finalized SP 800-63B-4 on 26 August 2025. Its main rules for password verifiers:

  • Length: at least 15 characters when the password is the only factor, at least 8 when it is part of MFA; allow long passwords.
  • No composition rules such as "one uppercase, one digit, one symbol": they produce predictable patterns.
  • No forced periodic changes, but a forced change when there is evidence of compromise.
  • Blocklist: check every new password against known breached passwords, dictionary words and context words such as the company name.
  • SMS and voice are "restricted" authenticators; at AAL2 verifiers must offer at least one phishing-resistant option.

In Entra ID, Password Protection applies a global banned-password list plus your own custom list (with words like the company name), and can extend this check to on-premises AD DS with an agent on the domain controllers. Many organizations still have a 90-day expiry policy from older guidance; removing it, together with a blocklist and MFA, follows the current standard.