Cómo funciona TOTP - El código de 6 dígitos generado por sincronización temporal
Qué es TOTP - Códigos de un solo uso que cambian cada 30 segundos
Time-based One-Time Password (TOTP) es el algoritmo detrás de Google Authenticator, Authy, Microsoft Authenticator y 1Password. El servidor y el dispositivo del usuario comparten una clave secreta, y ambos calculan un número de 6 dígitos combinando esa clave con la hora actual. El número cambia cada 30 segundos, y para iniciar sesión correctamente el usuario debe escribir los dígitos válidos en la ventana actual. RFC 6238 estandarizó este mecanismo en 2011, garantizando la interoperabilidad entre proveedores.
La mayor ventaja práctica de TOTP es que funciona sin conectividad de red una vez que el secreto se ha compartido. El servidor no necesita enviar nada al dispositivo, y el dispositivo no necesita consultar al servidor. Esto hace que TOTP sea más barato de operar a escala que las contraseñas de un solo uso por SMS, al tiempo que evita los ataques de intercambio de SIM que afectan a la autenticación por SMS.
HOTP - El predecesor basado en contador
TOTP se construye sobre HMAC-based One-Time Password (HOTP), definido en RFC 4226. HOTP utiliza un contador y una clave secreta, los procesa con HMAC-SHA-1 y extrae un número de 6 dígitos del resultado. Cada inicio de sesión exitoso incrementa el contador en ambos lados, de modo que el siguiente código es diferente. HOTP funciona sin ninguna fuente de tiempo, lo que lo hace adecuado para tokens de hardware sin reloj.
La desventaja de HOTP es la desincronización del contador. Si un usuario abre la aplicación autenticadora varias veces sin usar los códigos, el contador del dispositivo avanza mientras el del servidor permanece quieto. El servidor debe entonces buscar hacia adelante algunos valores para encontrar una coincidencia, lo que añade complejidad operativa. TOTP resuelve esto elegantemente reemplazando el contador con la hora actual dividida en intervalos de 30 segundos.
El algoritmo TOTP - Pasos temporales de 30 segundos
TOTP calcula el contador como la marca de tiempo Unix actual dividida entre 30 (división entera). Por ejemplo, en el tiempo Unix 1716000000 (18 de mayo de 2024 a las 14:40 UTC), el contador es 57200000. Ese contador se introduce en el algoritmo HOTP con el secreto compartido, produciendo un número de 6 dígitos. Treinta segundos después, el contador pasa a 57200001 y se genera un número completamente diferente.
El paso de 30 segundos de RFC 6238 equilibra usabilidad y seguridad. Demasiado corto y los usuarios no pueden teclear el código a tiempo; demasiado largo y los intentos de fuerza bruta tienen una ventana más amplia para acertar. Los servidores suelen aceptar también las ventanas de 30 segundos anterior y siguiente, proporcionando aproximadamente 90 segundos de tolerancia total. Diferentes servicios ajustan esto ligeramente: Steam Guard usa un paso de 30 segundos con variaciones propias, mientras que algunos tokens empresariales usan 60 segundos.
El secreto dentro del código QR - La URI otpauth
Cuando activas la autenticación de dos factores, el código QR en pantalla codifica una URI otpauth:// que contiene el secreto compartido. Una URI típica tiene este aspecto: otpauth://totp/Example:alice@example.com?secret=JBSWY3DPEHPK3PXP&issuer=Example. El secreto está codificado en Base32 (se usa Base32 porque evita caracteres que se confunden fácilmente en fuentes de pantalla). Las aplicaciones autenticadoras analizan esta URI y almacenan el secreto localmente.
Cualquiera que fotografíe el código QR puede clonar el generador de OTP, así que la pantalla de configuración debería mostrarse solo una vez y nunca durante una sesión de pantalla compartida. La mayoría de los servicios acompañan la configuración de TOTP con un conjunto de códigos de respaldo de un solo uso. Cada código de respaldo es una cadena aleatoria larga de uso único que evita TOTP, útil cuando se pierde el teléfono. Almacenar los códigos de respaldo en un gestor de contraseñas separado o impresos en un lugar seguro es la práctica estándar.
Desfase de reloj - La causa más común de fallo
Cuando la autenticación TOTP falla, la causa suele ser que el servidor y el dispositivo no están de acuerdo en la hora actual. Los servidores típicamente se sincronizan con UTC vía NTP, pero un teléfono con la hora ajustada manualmente, o uno que acaba de volver de un viaje internacional con la configuración confusa, puede desviarse un minuto o más. Google Authenticator incluye una función de «Corrección de hora» que obtiene la hora correcta de Google y ajusta los cálculos internos en consecuencia.
El desfase del lado del servidor es igual de peligroso. Los contenedores que funcionan sin sincronización NTP adecuada pueden desviarse decenas de segundos, especialmente en virtualización anidada. Los casos de estudio de la industria describen repetidamente caídas en las que todos los usuarios quedan bloqueados porque el reloj del servidor de autenticación se retrasó varios minutos. Para los sistemas que implementan TOTP, la sincronización NTP regular y las alertas ante fallos de sincronización son requisitos operativos innegociables.
Notas de implementación - De SHA-1 a SHA-256, protección contra repetición
TOTP usa por defecto HMAC-SHA-1, que RFC 6238 considera adecuado para los casos de uso de OTP. Las implementaciones más nuevas pueden seleccionar SHA-256 o SHA-512 mediante el parámetro algorithm en la URI otpauth. Las versiones antiguas de Google Authenticator no soportaban SHA-256, así que la compatibilidad retroactiva es la razón principal por la que la mayoría de servicios siguen usando SHA-1. Para implementaciones nuevas que solo apuntan a aplicaciones autenticadoras modernas, SHA-256 es una mejora razonable.
Los servidores también deben prevenir ataques de repetición. Si dos intentos de inicio de sesión llegan dentro de la misma ventana de 30 segundos, solo el primero debería tener éxito; de lo contrario, un atacante que haya capturado un código podría reutilizarlo. Almacenar el valor del contador utilizado más reciente por usuario y rechazar cualquier valor igual o inferior es la defensa canónica. La longitud predeterminada de 6 dígitos puede aumentarse a 7 u 8 dígitos mediante el parámetro digits para mayor entropía, a costa de una entrada ligeramente menos cómoda.
¿Te resultó útil este artículo?