Implementaciones MFA específicas: cómo funcionan por dentro

Mecánica técnica de las implementaciones MFA más usadas — TOTP, SMS OTP, push, FIDO2/WebAuthn, passkeys, magic links — con sus flujos, vulnerabilidades concretas y patrones de fallback. Más CAPTCHA: por qué no es autenticación pero sí un complemento útil.

Por qué este artículo es más técnico que el anterior

En el artículo anterior recorrimos las cinco categorías de factores de autenticación y mencionamos varias implementaciones de pasada. Ahora abrimos el capó. Cada implementación tiene una mecánica concreta — un protocolo, un flujo, un conjunto de vulnerabilidades específicas, decisiones de diseño que se cuelan en el código real. Si vas a implementar autenticación en una app o auditar la de otra, este es el nivel de detalle que necesitas.


Voy a asumir que tienes background técnico (eres desarrollador o ingeniero IAM). Verás referencias a RFC, fórmulas, pseudocódigo, y diagramas de secuencia con detalle de protocolo. La idea es que termines este artículo capaz de:

  • Explicar cómo se calcula un código TOTP.
  • Diagramar la ceremonia de WebAuthn de registro y autenticación.
  • Identificar cuándo SMS OTP es aceptable y cuándo no lo es.
  • Diseñar fallbacks razonables para cuando un usuario pierde su factor primario.


TOTP y HOTP: el código que cambia cada 30 segundos

Los algoritmos de One-Time Password son el caballo de batalla del MFA empresarial desde mediados de los 2000s. Son simples, abiertos y funcionan offline.


HOTP: el predecesor (RFC 4226)

HOTP (HMAC-based One-Time Password) genera códigos a partir de una semilla compartida más un contador. Cada vez que se genera un código, el contador avanza:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C))
 
donde:
  K = clave secreta (semilla compartida)
  C = contador de 8 bytes (incrementa con cada código)

El servidor y el cliente mantienen el mismo contador. Cuando el usuario presenta un código, el servidor lo recalcula con su contador actual. Si coincide, valida y avanza el contador.


Problema: si el contador se desincroniza (el usuario generó un código pero no lo usó), todo se rompe. Por eso casi nadie usa HOTP puro hoy — se usa TOTP.


TOTP: el estándar actual (RFC 6238)

TOTP (Time-based One-Time Password) reemplaza el contador por el tiempo dividido en ventanas de 30 segundos:

T = floor((tiempo_unix_actual - T0) / X)
 
TOTP(K) = HOTP(K, T)
 
donde:
  T0 = típicamente 0 (Unix epoch)
  X  = típicamente 30 segundos

Servidor y cliente comparten reloj (UTC) y la misma semilla. Cada 30 segundos generan el mismo código. Cuando el usuario lo presenta, el servidor recalcula y compara.


Enrolamiento de TOTP

sequenceDiagram
  accTitle: Ceremonia de enrolamiento de TOTP
  accDescr: El usuario activa TOTP; el servidor genera un secreto de 160 bits y lo devuelve como un código QR otpauth; la app autenticadora lo escanea y almacena el secreto localmente; el usuario ingresa un código de prueba y el servidor lo verifica antes de marcar TOTP como enrolado.
  actor U as Usuario
  participant App as App de auth
  participant Srv as Servidor
  U->>Srv: Activa TOTP en la cuenta
  Srv->>Srv: Genera secreto K (160 bits)
  Srv->>U: Devuelve QR con otpauth://totp/...?secret=K
  U->>App: Escanea QR (Google Auth, Authy)
  App->>App: Almacena K localmente
  U->>Srv: Ingresa código de prueba
  Srv->>Srv: Verifica que el código coincida
  Srv->>U: TOTP enrolado
El enrolamiento vincula un secreto compartido a la app vía QR — tras un código de prueba, ambos lados generan los mismos códigos de 30 segundos.

El URI otpauth:// es el formato estándar de Google Authenticator, aceptado por casi todas las apps de autenticación.


Manejo de drift de reloj

Los relojes derivan. Si el del usuario va 15 segundos atrasado, su código será inválido en el servidor. La solución estándar es aceptar una ventana de tolerancia — típicamente ±1 ventana, lo que da 90 segundos efectivos:

def validate_totp(K, code_received, current_time):
    for offset in [-1, 0, 1]:
        T = (current_time / 30) + offset
        expected = HOTP(K, T)
        if expected == code_received:
            return True
    return False

Demasiada tolerancia rompe la seguridad; muy poca rompe la usabilidad.


Vulnerabilidades de TOTP

  • Phishing en tiempo real: un atacante presenta un sitio falso, el usuario escribe TOTP, el atacante lo reenvía en segundos al sitio real. El TOTP no protege contra esto.
  • Robo del secreto K: si la app del usuario es comprometida (ej. malware en el teléfono), el atacante extrae K y genera códigos perpetuamente. Por eso las semillas no deberían poder exportarse fácilmente.
  • Backup inseguro: apps como Authy permitían backup en cloud. Si la cuenta de Authy se compromete, los TOTPs de todos los servicios se exponen.

SMS OTP: cómodo pero indefendible para alto valor

Cómo funciona

El flujo es el más simple de todas las implementaciones de aquí: inicias sesión con usuario + contraseña, el servidor genera un código de 6 dígitos y se lo entrega a un SMS gateway, el gateway lo envía a tu número registrado, y lo escribes de vuelta en la app, que verifica que coincida y no haya expirado. El código tiene un TTL típico de 5-10 minutos.


Vulnerabilidades concretas

  • SIM swapping: el atacante convence a la operadora (con ingeniería social, soborno o documentos falsos) de portar tu número a su SIM. Toma minutos. Caso famoso: el robo de la cuenta del CEO de Twitter en 2019.
  • SS7 attacks: el protocolo SS7 que usan las operadoras para enrutar SMS tiene vulnerabilidades conocidas que permiten interceptar mensajes desde otros operadores. Demostrado en producción.
  • Phishing en tiempo real: igual que TOTP, vulnerable.
  • Operadoras comprometidas: empleados internos de la operadora pueden ver SMS.
  • Reuso de números: cuando un número se libera y se reasigna, el nuevo dueño puede recibir SMS destinados al antiguo.

Cuándo (todavía) tiene sentido

Aunque NIST SP 800-63B lo desaconseja para AAL2, SMS OTP sigue siendo útil cuando:

  • Es mejor que SFA: tener algún MFA, aunque sea débil, es mejor que solo contraseña.
  • Tu base de usuarios no tiene smartphones modernos y necesitas algo universal.
  • Es un canal de fallback secundario, no el primario.


Email OTP: solo tan seguro como el correo

Cómo funciona

Idéntico al SMS pero por correo: la app genera un código, lo envía al email registrado, el usuario lo escribe.


El problema fundamental

La seguridad de email OTP se reduce a la seguridad del email mismo. Si la cuenta de email del usuario está protegida solo con contraseña (sin MFA), el “MFA con email OTP” es esencialmente un factor único disfrazado. Un atacante con acceso al email puede:

  1. Iniciar el flujo de login en la app objetivo.
  2. Recibir el código en el email comprometido.
  3. Completar el login.

Y si el email tiene “olvidé contraseña” como mecanismo de recovery, basta con el email para tomar control de cuentas en cualquier servicio donde uses ese email.


Cuándo es razonable

  • Apps de bajo valor donde la fricción de TOTP no se justifica.
  • Como canal de fallback cuando se pierde el dispositivo TOTP, con verificaciones adicionales.
  • En CIAM para verificación de email durante registro (no para login recurrente).

Push notifications: cómodo pero atrapó al CEO de Uber

Cómo funciona

sequenceDiagram
  accTitle: Flujo de autenticación por notificación push
  accDescr: Tras iniciar sesión con email y contraseña, el IdP pide a un servicio de push que notifique a la app móvil registrada; el usuario aprueba con un toque; la app móvil confirma con una firma del dispositivo; el IdP devuelve un token y la sesión inicia.
  actor U as Usuario
  participant App as App web
  participant IdP as IdP
  participant PushSvc as Push service
  participant Phone as App móvil
  U->>App: Login con email + password
  App->>IdP: Autentica primer factor
  IdP->>PushSvc: Solicita push al dispositivo registrado
  PushSvc->>Phone: Notificación: "¿eres tú?"
  U->>Phone: Aprueba (un toque)
  Phone->>IdP: Confirma aprobación con firma del dispositivo
  IdP->>App: Token con claims
  App->>U: Sesión iniciada
Un toque para aprobar — la misma comodidad que abusan los ataques de MFA bombing.

Buena UX: un toque y entras. Pero introdujo un riesgo nuevo.


MFA fatigue / push bombing

El atacante, con tu contraseña ya robada, dispara push notifications repetidas. La víctima — fatigada, distraída, medio dormida — eventualmente aprueba una. Caso famoso: breach de Uber 2022, donde un atacante de Lapsus$ entró así.


Mitigaciones modernas

  • Number matching: en lugar de aprobar con un toque, el push muestra un número (ej. 47) que el usuario debe escribir/seleccionar en la app de origen. Elimina la aprobación automática.
  • Geo + contexto en el push: el push muestra “Login desde Tokio. ¿Eres tú?”. Si el usuario está en Madrid, ve la inconsistencia y rechaza.
  • Rate limiting en pushes: si se disparan más de 3 pushes en 5 minutos, se bloquea automáticamente la cuenta y se alerta.
  • Confirmación biométrica: el push requiere Face ID o huella en la app móvil para aprobar. No basta con un toque.

Microsoft Authenticator, Duo y Okta Verify implementan number matching por defecto desde 2023.


FIDO2 / WebAuthn: el estándar phishing-resistant

FIDO2 es el conjunto de estándares (WebAuthn + CTAP) que reemplaza contraseñas con criptografía asimétrica anclada al dispositivo del usuario. Es lo más fuerte que existe hoy en autenticación de consumidor.


Por qué es phishing-resistant

La diferencia clave con todo lo anterior: el dominio del sitio se incluye en la firma. La llave no firma “soy María”; firma “soy María en banco.com”. Si te conectas a banc0.com (con cero), la firma incluye el dominio falso y el servidor real la rechaza.


Las dos ceremonias de WebAuthn

WebAuthn tiene dos flujos: registro (la primera vez) y autenticación (cada login).


Registro (Attestation)

sequenceDiagram
  accTitle: Ceremonia de registro (attestation) de WebAuthn
  accDescr: El servidor envía un challenge y opciones; el navegador llama a navigator.credentials.create; el autenticador pide un gesto, genera un par de claves y almacena la privada localmente, y devuelve la clave pública con una attestation firmada; el navegador reenvía la pública y el servidor la almacena asociada al usuario.
  participant U as Usuario
  participant Browser as Navegador
  participant Auth as Autenticador (YubiKey, TPM, Secure Enclave)
  participant Srv as Servidor
  Srv->>Browser: Challenge + opciones
  Browser->>Auth: navigator.credentials.create()
  Auth->>U: Pide gesto (toque, biométrico)
  Auth->>Auth: Genera par de claves
  Auth->>Auth: Almacena clave privada localmente
  Auth->>Browser: Pública + attestation firmada
  Browser->>Srv: Envía clave pública
  Srv->>Srv: Almacena pública asociada al usuario
Registro: la clave privada se genera en el autenticador y nunca sale de él; el servidor solo ve la clave pública.

El servidor almacena la clave pública (no la privada — que jamás sale del autenticador) y queda lista para el siguiente login.


Autenticación (Assertion)

sequenceDiagram
  accTitle: Ceremonia de autenticación (assertion) de WebAuthn
  accDescr: El navegador solicita un challenge; el servidor devuelve un challenge aleatorio y el origin; el navegador llama a navigator.credentials.get incluyendo el origin; el autenticador pide un gesto y firma el challenge más el origin con la clave privada; el navegador envía la firma y el servidor la verifica con la clave pública antes de iniciar la sesión.
  participant U as Usuario
  participant Browser as Navegador
  participant Auth as Autenticador
  participant Srv as Servidor
  U->>Browser: Inicia login
  Browser->>Srv: Solicita challenge
  Srv->>Browser: Challenge aleatorio + origin
  Browser->>Auth: navigator.credentials.get() — incluye origin
  Auth->>U: Pide gesto
  Auth->>Auth: Firma challenge + origin con clave privada
  Auth->>Browser: Firma
  Browser->>Srv: Envía firma
  Srv->>Srv: Verifica firma con clave pública
  Srv->>Browser: Sesión iniciada
Autenticación: la firma cubre el challenge y el origin, así un dominio parecido no puede reutilizarla.

Por qué importa el origin

En el paso “Firma challenge + origin”: si el sitio falso tiene origin banc0.com y el navegador lo envía al autenticador, la firma resultante incluye banc0.com. El servidor real (banco.com) recibe esa firma y verifica contra su clave pública, pero detecta que el origin firmado no coincide con su propio dominio. Rechaza la autenticación.


Eso significa que incluso si el usuario es engañado y “aprueba” en un sitio falso, el atacante no puede usar la firma para acceder al sitio real. Eso es lo que ningún OTP/push tradicional logra.


Tipos de autenticadores

  • Roaming authenticators: dispositivos separados que se conectan vía USB/NFC/Bluetooth (YubiKey, Google Titan).
  • Platform authenticators: integrados al dispositivo (Touch ID, Face ID, Windows Hello, Android biometric).

Passkeys: WebAuthn sincronizado entre dispositivos

Los passkeys son la evolución consumer-friendly de WebAuthn. Resuelven dos limitaciones del WebAuthn clásico:

  1. Si pierdes el dispositivo, pierdes la credencial — UX terrible para usuarios finales.
  2. Cada dispositivo necesita registro independiente — fricción al cambiar de teléfono.

Discoverable credentials

Los passkeys son credenciales descubribles: el autenticador almacena tanto la clave privada como un identificador del usuario. En login, el usuario ni siquiera necesita escribir su email — el navegador le ofrece “iniciar sesión con tu passkey de María García” directamente.


Sincronización en cloud

La diferencia operativa principal: la clave privada se sincroniza vía iCloud Keychain, Google Password Manager o Windows Hello entre los dispositivos del mismo usuario. Si tienes iPhone + Mac + iPad, el passkey funciona en los tres sin enrolar cada uno.


flowchart LR
  accTitle: Passkeys sincronizados entre los dispositivos de un usuario
  accDescr: Un passkey creado en un iPhone se sincroniza mediante un iCloud Keychain cifrado de extremo a extremo hacia el Mac y el iPad del mismo usuario, y puede recurrir a un dispositivo Windows mediante un código QR cross-device.
  iPhone[iPhone<br/>passkey original] --> iCloud[(iCloud Keychain<br/>cifrado E2E)]
  iCloud --> Mac[Mac<br/>passkey sincronizado]
  iCloud --> iPad[iPad<br/>passkey sincronizado]
  iCloud -.fallback.-> Windows[Windows con QR<br/>cross-device]
Un passkey, todos los dispositivos — sincronizado de extremo a extremo por el keychain de la plataforma, con un QR cross-device como vía de escape.

Account recovery

Cuando pierdes todos tus dispositivos:

  • Recovery via cloud account: si recuperas tu Apple ID o Google account, recuperas todos los passkeys.
  • Recovery via cross-device: en otro dispositivo, escaneas un QR para temporalmente usar el passkey.

Limitaciones actuales

  • Vendor lock-in suave: tus passkeys de iCloud no se exportan a Google fácilmente. Cambiar de ecosistema es trabajoso.
  • Adopción heterogénea: no todas las apps soportan passkeys todavía. Mejorando rápido.
  • Para B2B regulado: algunas regulaciones exigen FIDO2 con autenticador hardware (no sincronizado), por temor al compromiso del cloud account.


Un magic link es una URL única enviada al email del usuario que, al hacer click, completa el login. Adoptado por Slack, Notion, Medium y muchos productos modernos.


Cómo funciona

sequenceDiagram
  accTitle: Flujo de login con magic link
  accDescr: El usuario ingresa su email; el servidor genera un token aleatorio asociado al email con un TTL y envía por correo un enlace que lo contiene; el usuario hace click en el enlace, que navega a un endpoint de auth; el servidor valida el token, lo marca como usado para que no pueda reutilizarse, e inicia la sesión.
  actor U as Usuario
  participant App as App web
  participant Srv as Servidor
  participant Mail as Email
  U->>App: Ingresa email
  App->>Srv: Solicita magic link
  Srv->>Srv: Genera token aleatorio
  Srv->>Srv: Asocia con email + TTL
  Srv->>Mail: Envía link con token
  U->>Mail: Click en link
  Mail->>App: Navega a /auth?token=...
  App->>Srv: Valida token
  Srv->>Srv: Marca token como usado (no reutilizable)
  Srv->>App: Sesión iniciada
Un token de un solo uso y vida corta hace ida y vuelta por el buzón — la seguridad se reduce a la del email.

Patrones de seguridad importantes

  • Token único de uso: una vez consumido, no funciona otra vez. Defensa contra replay.
  • TTL corto: 10-15 minutos típicamente. Si caduca, el usuario solicita uno nuevo.
  • Validación de IP/device opcional: si el link se abre desde un país o dispositivo distinto al de la solicitud, requerir confirmación adicional.
  • Anti-CSRF: el token debe ser largo (256 bits idealmente), aleatorio, y no predecible.

Vulnerabilidades

  • Email comprometido = cuenta comprometida: igual que email OTP, la seguridad se reduce a la del email.
  • Email forwarding mal configurado: si el email reenvía a otra cuenta automáticamente, el reenvío puede leer el link.
  • Phishing: el atacante envía un email idéntico al magic link real con su propio link, y el usuario lo clickea. (Mitigación: estándares como BIMI ayudan a verificar el emisor.)

Combinándolos

Patrón común en apps modernas: magic link como factor primario + push o TOTP como segundo. Combinas la simplicidad del magic link con la seguridad de un segundo factor independiente.


CAPTCHA, reCAPTCHA, hCaptcha: anti-bot, no autenticación

Aclaración crítica

CAPTCHA no es un factor de autenticación. No prueba que eres tú; prueba que eres humano (o que actúas como uno). Es un complemento al login, no un sustituto. La gente los confunde porque aparecen en formularios de login junto a la contraseña.


Para qué sirven realmente

CAPTCHAs protegen contra:

  • Credential stuffing: un atacante con millones de credenciales filtradas las prueba en masa. CAPTCHA encarece cada intento.
  • Bots de scraping de cuentas: registrar 10,000 cuentas falsas en una hora.
  • Brute force: si rate limiting falla, CAPTCHA le agrega fricción.

Tipos modernos

TipoCómo funciona
reCAPTCHA v2 (“I’m not a robot”)Checkbox; analiza el movimiento del mouse y el comportamiento
reCAPTCHA v3Invisible; devuelve un score 0.0-1.0 sin interacción del usuario
hCaptchaAlternativa que paga a sitios por sus datos de entrenamiento
Cloudflare TurnstileAnti-bot moderno, privacy-first, sin tracker de Google
Proof-of-Work CAPTCHAEl navegador resuelve un puzzle criptográfico (ej. Anubis)

Privacidad

Google reCAPTCHA recolecta datos de comportamiento masivos, lo que incomoda a varios operadores. Cloudflare Turnstile y hCaptcha se posicionan como alternativas privacy-first.



Patrones de fallback y recovery

Por buena que sea tu autenticación primaria, los usuarios pierden dispositivos, olvidan contraseñas, cambian de número. Necesitas planes de recovery — y son el punto más débil de muchos sistemas, porque para que el usuario recupere su cuenta, el atacante también puede aprovechar la misma vía.


Tabla de patrones comunes

Patrón de recoveryProsContras / amenazas
Email “forgot password”Universal, fácilSolo tan seguro como el email
Códigos de respaldo (10 OTP de un solo uso)Independiente de dispositivosEl usuario rara vez los guarda bien
Identity proofing manual (foto + documento)RobustoCaro, lento, expone PII al humano que valida
Trusted device listUX buenoSi todos los devices se pierden, no funciona
Recovery por contacto verificado (otra persona)Bueno para Apple FamilyMuy nuevo, requiere setup previo

El principio fundamental

Tu vía de recovery no debe ser más débil que tu autenticación primaria. Si tu primario es passkey + biometría pero recuperas con SMS OTP, has reducido la seguridad efectiva del sistema al nivel del SMS. Un atacante atacará por la vía más débil.


Cómo elegir: tres escenarios prácticos

La pregunta práctica que más me toca responder en consultoría es: “¿qué factor implemento para mi caso?”. No hay respuesta única. Depende del riesgo, la audiencia y la madurez técnica del equipo. Tres escenarios típicos:


Escenario 1: app móvil de banca para consumidor en Centroamérica

  • Audiencia: clientes de todas las edades, muchos con teléfonos de gama media.
  • Restricciones: regulación local exige MFA real; UX debe ser fluida.
  • Recomendación: passkey como factor primario (donde el dispositivo lo soporta) + TOTP en app + biometría local. Fallback de SMS OTP solo para clientes con teléfonos antiguos. Step-up con PIN transaccional para operaciones de más de $200.
  • Por qué: passkeys eliminan phishing (vector dominante en banca), TOTP cubre los casos donde passkey aún no es viable, y SMS solo aparece cuando no hay alternativa.

Escenario 2: app interna de RR. HH. para 200 empleados

  • Audiencia: empleados conectándose desde laptops corporativas o BYOD.
  • Restricciones: presupuesto bajo, equipo pequeño que mantiene la app.
  • Recomendación: SSO contra el IdP corporativo (Microsoft Entra ID o Google Workspace) que ya tiene MFA configurado. La app no implementa MFA propio.
  • Por qué: reusar la inversión de MFA del IdP corporativo es lo más eficiente. Implementar MFA propio en cada app interna es duplicar trabajo y multiplicar superficies de ataque.

Escenario 3: panel administrativo de operaciones críticas (admin de cluster K8s)

  • Audiencia: 8 ingenieros de plataforma con acceso a producción.
  • Restricciones: una credencial comprometida = catástrofe.
  • Recomendación: FIDO2 con llave hardware obligatoria (una YubiKey para cada ingeniero) + step-up para acciones destructivas (delete cluster, modificar IAM policies) que requieren approval de un segundo ingeniero.
  • Por qué: este es el caso donde se justifica el costo y la fricción del hardware key. Los passkeys sincronizados son insuficientes — quieres que la clave privada nunca abandone un chip físico.


Tabla comparativa: cuándo usar qué

FactorPhishing-resistantVulnerable aBuen primary para
ContraseñaNoPhishing, leaks, reusoNada en 2026
TOTPNoPhishing en tiempo realApps internas, donde no aplica passkey
SMS OTPNoSIM swap, SS7Solo fallback
Email OTPNoEmail comprometidoSolo fallback
Push notificationParcialMFA bombing (sin number matching)Workforce con number matching
FIDO2 hardwarePérdida física, costoAdmins, cuentas críticas
PasskeysCompromiso de cloud accountConsumidor en general
Magic linkNoEmail comprometidoApps simples + 2do factor
CAPTCHAno aplica — no es factorBots avanzadosAnti-bot complementario

Recapitulación

Las implementaciones MFA no son intercambiables. Cada una resuelve un problema concreto y tiene su modelo de amenaza específico:

  • TOTP/HOTP: simple, offline, vulnerable a phishing en tiempo real.
  • SMS OTP: cómodo, pero vulnerable a SIM swap y SS7. No para alto valor.
  • Email OTP: solo tan seguro como el email. Útil como fallback acotado.
  • Push: gran UX, pero requiere number matching para no caer en MFA bombing.
  • FIDO2/WebAuthn: el estándar oro phishing-resistant para cuentas críticas.
  • Passkeys: la versión consumer-friendly de WebAuthn, ideal para CIAM moderno.
  • Magic links: simples, pero email-dependientes.
  • CAPTCHAs: anti-bot, no autenticación. No los confundas.

Y una regla de hierro para cualquier diseño: tu vía de recovery no debe ser más débil que tu autenticación primaria.



Tres preguntas para autoevaluarte

  1. Diseña el flujo de recovery para un usuario que perdió su iPhone (donde tenía passkeys + TOTP). ¿Qué pasos pones, qué validaciones haces, y por qué cada una?
  2. Tu CTO dice “implementemos passkeys y eliminemos contraseñas en una semana”. ¿Qué tres advertencias le darías sobre transición y compatibilidad?
  3. Una app permite login con magic link sin segundo factor para todas las acciones. Diseña tres step-up que recomendarías agregar y para qué tipos de operación.

Preguntas frecuentes

¿Cómo se calcula un código TOTP?

TOTP aplica HOTP a un contador de tiempo: T = floor((tiempo_unix_actual - T0) / X), donde T0 suele ser 0 y X es una ventana de 30 segundos, y luego TOTP(K) = HOTP(K, T) = Truncate(HMAC-SHA-1(K, T)). El servidor y el cliente comparten el secreto K y un reloj UTC, así que ambos generan el mismo código de 6 dígitos cada 30 segundos. Está definido en el RFC 6238.

¿Es el OTP por SMS suficientemente seguro para MFA?

Solo como último recurso. El SMS OTP es vulnerable a SIM swapping, interceptación por SS7, phishing en tiempo real y reciclaje de números, y NIST SP 800-63B lo desaconseja para AAL2 desde 2017. Sigue siendo mejor que solo una contraseña, así que es aceptable como fallback secundario o para usuarios sin smartphone — pero nunca como factor primario para dinero, datos sensibles o acceso administrativo.

¿Qué hace que FIDO2/WebAuthn sea resistente a phishing?

El origen (dominio) del sitio se incluye en el challenge firmado. El autenticador firma 'soy este usuario en bank.com,' no solo 'soy este usuario,' así que un dominio parecido como banc.com produce una firma que el servidor real rechaza. Aunque engañen al usuario para aprobar en un sitio falso, el atacante no puede reutilizar esa firma contra el real — algo que ningún OTP ni push logra.

¿Cuál es la diferencia entre un passkey y una llave hardware FIDO2?

Ambos usan la criptografía asimétrica de WebAuthn, pero un passkey es una credencial discoverable sincronizada entre los dispositivos del usuario mediante iCloud Keychain, Google Password Manager o Windows Hello, mientras que una llave hardware FIDO2 (YubiKey, Titan) mantiene la clave privada en un chip físico que nunca se sincroniza. Los passkeys son lo mejor para consumidores; las llaves hardware para administradores y cuentas reguladas donde el miedo principal es comprometer la cuenta en la nube.

¿Es CAPTCHA un factor de autenticación?

No. CAPTCHA demuestra que eres humano, no que eres una persona concreta, así que es una herramienta anti-bot, no autenticación. Complementa el login al elevar el costo del credential stuffing y el scraping, pero nunca debe reemplazar un factor ni ser tu única defensa contra fuerza bruta — el rate limiting y el bloqueo progresivo siguen siendo los controles principales.