Por Qué Mi Código 2FA No Funciona: Guía de Solución
Security Tools

Por Qué Mi Código 2FA No Funciona: Guía de Solución

Abres tu aplicación de autenticación, lees los seis dígitos, los tecleas y el sitio dice que el código no es válido. Lo intentas otra vez — sigue rechazado. Pocos errores de seguridad son tan frustrantes, porque todo parece correcto: la app muestra un código, el código es reciente y estás seguro de haberlo tecleado bien. La buena noticia es que casi todos los casos de "código 2FA no funciona" se reducen a un puñado de causas, y pueden ordenarse por la frecuencia con la que ocurren en realidad. Esta guía las recorre por orden de probabilidad, explica por qué cada una rompe el código y muestra cómo arreglarlo. Si quieres ver el mecanismo directamente, nuestro Generador TOTP te deja observar cómo cambian los códigos contra un reloj en vivo, para que reproduzcas y diagnostiques el fallo tú mismo.

Primero, Cómo Se Calcula Realmente un Código TOTP

Las contraseñas de un solo uso basadas en tiempo están definidas por la RFC 6238. El algoritmo es determinista: toma un secreto compartido (fijado durante el alta), la hora Unix actual y un pequeño conjunto de parámetros, y produce un código. El paso crítico es que la hora actual se divide en ventanas fijas — por defecto de 30 segundos cada una — y el número de ventana se convierte en un contador. Ese contador pasa por HMAC con el secreto compartido, y el resultado se trunca a los dígitos finales que ves. Tanto tu app como el servidor ejecutan exactamente el mismo cálculo. Si ambos coinciden en el secreto, los parámetros y la ventana de tiempo actual, producen el mismo código. Si cualquiera de esos tres discrepa, los códigos difieren y el servidor rechaza el tuyo. Casi todo fallo es uno de esos tres desalineándose. Nuestro artículo pilar, cómo funciona la autenticación TOTP, cubre la derivación completa si quieres el detalle de fondo.

Causa #1 (Con Diferencia la Más Común): El Reloj de Tu Dispositivo Está Desincronizado

Esta es la mayor fuente de códigos rechazados, así que empieza aquí antes que nada. Como el contador proviene de la hora de reloj de tu propio dispositivo, un teléfono cuyo reloj esté aunque sean un par de minutos desfasado calcula el código para la ventana de 30 segundos equivocada. La matemática se ejecuta perfectamente; solo que se ejecuta sobre la entrada equivocada. Si tu reloj va 90 segundos adelantado, tu app te está mostrando en efecto un código de tres ventanas en el futuro, y el servidor — que confía en su propia hora precisa — ve un código que no coincide con la ventana que espera, así que lo rechaza.

Lo sutil es que el error de reloj no tiene que ser grande. Los servidores suelen aceptar una pequeña ventana de deriva de uno o dos pasos a cada lado (unos ±30 a ±60 segundos) para tolerar desfases menores y el retardo de transmisión. Esa tolerancia es exactamente por lo que un teléfono con dos o tres minutos de desfase falla siempre mientras que uno con solo veinte segundos aún funciona. También explica por qué el fallo puede parecer aleatorio: justo después de un cambio manual de la hora o un fallo relacionado con la zona horaria, cruzas el límite de tolerancia y los códigos empiezan a ser rechazados en silencio.

La solución es dejar de poner la hora a mano y dejar que la red la fije:

  • Android: Ajustes → Sistema → Fecha y hora → activa Fecha y hora automáticas (usa la hora de red). Desactiva cualquier ajuste manual.
  • iPhone: Ajustes → General → Fecha y hora → activa Ajustar automáticamente. Si ya está activado, desactívalo y vuelve a activarlo para forzar una resincronización.
  • Windows: Configuración → Hora e idioma → Fecha y hora → activa Establecer la hora automáticamente y pulsa Sincronizar ahora.
  • macOS: Ajustes del Sistema → General → Fecha y hora → activa Ajustar la fecha y la hora automáticamente.

La hora de red automática mantiene tu dispositivo continuamente alineado con relojes de referencia, mucho más preciso de lo que cualquier persona puede ajustar un reloj a mano. Tras activarla, espera unos segundos a que la sincronización se aplique y luego lee un código nuevo.

Algunas apps de autenticación llevan además su propia defensa contra esto. Google Authenticator, por ejemplo, tiene una opción "Corrección de hora para los códigos" (en Ajustes) que consulta un servidor de tiempo, mide el desfase entre el reloj de tu dispositivo y la hora real, y aplica esa corrección internamente al generar códigos — sin cambiar el reloj del sistema. Si no puedes arreglar el reloj del dispositivo de inmediato (un teléfono gestionado por la empresa, por ejemplo), ejecutar esa corrección hace que tus códigos vuelvan a aceptarse. Si tu app carece de ese ajuste, corregir el reloj del sistema operativo es la vía fiable.

Causa #2: El Servicio Usa Parámetros No Predeterminados (Algoritmo, Dígitos o Periodo)

La RFC 6238 tiene valores por defecto — HMAC-SHA-1, 6 dígitos, un periodo de 30 segundos — y la gran mayoría de servicios los usan. Pero el estándar permite explícitamente otras opciones, y algunos servicios las eligen: SHA-256 o SHA-512 en lugar de SHA-1, 8 dígitos en vez de 6, o un periodo de 60 segundos en vez de 30. Cuando te diste de alta, esos parámetros debían transportarse en el QR de configuración (la URI otpauth:// tiene campos algorithm, digits y period). Si tu autenticador ignoró alguno — o si tecleaste el secreto a mano y la app recurrió a sus valores por defecto — tu app calcula códigos SHA-1 de 6 dígitos mientras el servidor espera códigos SHA-256 de 8 dígitos. Todos los códigos serán incorrectos, y lo serán de forma consistente, que es la señal que lo distingue de un problema de reloj.

Cómo reconocerlo: si el servidor pide un código de 8 dígitos pero tu app solo muestra 6, el número de dígitos no coincide — eso es obvio. El desajuste de algoritmo es invisible desde fuera (ambos producen un código de la longitud correcta) pero falla idénticamente cada vez sin importar tu reloj. Si lo sospechas, vuelve a darte de alta desde el QR original con una app que respete los parámetros, o verifica los valores directamente. Nuestro Generador TOTP expone los parámetros avanzados — algoritmo, número de dígitos y periodo — para que puedas ajustarlos a los del servicio y confirmar qué combinación produce el código que el servidor acepta. Nuestro artículo complementario sobre cuándo los servicios usan SHA-256 o TOTP de 8 dígitos enumera las situaciones en que esto aparece de verdad y cómo detectarlo.

Por Qué Mi Código 2FA No Funciona: Guía de Solución

Causa #3: El Secreto Se Tecleó Mal o Se Transcribió Erróneamente al Darse de Alta

Si configuraste la cuenta tecleando la clave secreta a mano en vez de escanear el QR, un solo carácter equivocado significa que tu app y el servidor quedan sembrados con secretos distintos — y secretos distintos nunca pueden producir códigos coincidentes. Los secretos TOTP se codifican en base32, que usa las letras A–Z y los dígitos 2–7. Ese alfabeto omite deliberadamente los caracteres visualmente ambiguos, pero los errores de transcripción se cuelan igual: un 0 escrito donde va una O, un 1 por una I o una l, un 8 por una B, o un carácter perdido o duplicado. Base32 además no distingue mayúsculas y se agrupa a menudo en bloques de cuatro con espacios — los espacios y las mayúsculas son cosméticos, pero las letras y los dígitos deben ser exactamente correctos.

La firma de un secreto erróneo es la misma que la de un desajuste de parámetros: todos los códigos fallan, de inmediato, por muy bien que esté tu reloj. Si no puedes descartar un error de tecleo, la solución más limpia es eliminar la cuenta de tu autenticador y volver a darte de alta escaneando el QR, que transfiere el secreto sin ningún tecleo manual. Cuando solo se ofrece un secreto en texto, pégalo en vez de reescribirlo, y compruébalo contra el alfabeto A–Z/2–7 de base32 antes de guardar.

Causa #4: Reutilizaste un Código, o lo Introdujiste un Instante Demasiado Tarde

Un código TOTP solo es válido para su propia ventana de tiempo. Dos errores de temporización relacionados hacen que un código que era correcto sea rechazado:

  • Introducirlo justo tras el cambio de ventana. Si a un código le quedan solo unos segundos cuando empiezas a teclear, puede caducar entre que lo lees y lo envías. El servidor ya ha pasado a la ventana siguiente y el código que enviaste pertenece a la anterior. Muchos servidores aceptan la ventana inmediatamente anterior para suavizar esto, pero esa gracia no está garantizada. El hábito que lo evita: cuando el anillo de cuenta atrás está casi vacío, espera a que el código se refresque y usa el nuevo en vez de correr con el viejo.
  • Reutilizar un código que el servidor ya consumió. Las buenas implementaciones rechazan un código que ya se usó con éxito dentro de su ventana, precisamente para que un código interceptado no pueda reproducirse. Si enviaste un código, te interrumpieron y envías el mismo código otra vez, puede ser rechazado como ya gastado aunque parezca actual. Espera a un código nuevo y envía ese.

Causa #5: Tecleaste una Captura de Pantalla Antigua o un Código Caducado

Los códigos capturados fuera de su momento llegan muertos. Si hiciste una captura de un código para pegarlo luego, o estás leyendo de una notificación que lleva rato en pantalla, la ventana subyacente ya pasó hace mucho aunque los dígitos sigan visibles. El número en pantalla es una instantánea de una ventana que ya no existe. Genera siempre — y usa de inmediato — un código en vivo de la propia app; nunca guardes un código TOTP para después.

Causa #6: Está Seleccionada la Entrada de Cuenta Equivocada en la App

Si usas un solo autenticador para muchos servicios, es fácil leer el código de la fila equivocada — dos cuentas de trabajo, o un inicio personal y otro de trabajo del mismo proveedor, una junto a otra. El código es perfectamente válido; solo que pertenece a otra cuenta, así que el servidor en el que inicias sesión lo rechaza. Comprueba que la etiqueta y la cuenta/correo de la entrada coinciden con la cuenta exacta en la que estás entrando, y luego lee el código de esa fila concreta.

Un Orden Rápido de Diagnóstico

Cuando un código es rechazado, recorre las causas en este orden, porque va de lo más probable a lo menos probable y cada paso descarta o confirma una clase de problema:

  • ¿Falla solo a veces, o cerca del final de la cuenta atrás? Sospecha de temporización (Causa #4/#5) — espera un código nuevo.
  • ¿Falla siempre, de inmediato, con un código nuevo? El reloj, los parámetros o el secreto están mal. Primero activa la hora de red automática (Causa #1) y prueba de nuevo — esto arregla la mayor parte de los casos.
  • ¿Sigue fallando siempre con un reloj correcto? Revisa dígitos y algoritmo (Causa #2), luego vuelve a darte de alta por QR para descartar un secreto mal tecleado (Causa #3).
  • ¿Varias cuentas en la app? Confirma que lees la fila correcta (Causa #6).

Entender por qué cada una de estas rompe el código — en vez de solo seguir pasos — hace que la próxima vez la solución sea obvia. Como TOTP es totalmente determinista, un código rechazado siempre significa que una de las tres entradas (secreto, parámetros u hora de ventana) está desalineada, y este orden encuentra cuál más rápido. Para ver la parte móvil con tus propios ojos, abre el Generador TOTP: muestra la cuenta atrás, avisa cuando el reloj de tu navegador parece desfasado y te deja fijar los parámetros avanzados para reproducir exactamente la combinación que tu servicio espera.

← Volver al Blog