⏱️ Criptografía y arquitectura ✓ Verificado para 2026

TOTP vs HOTP explicados: Diferencias clave, funcionamiento y seguridad

Millones de desarrolladores e ingenieros de seguridad consultan códigos dinámicos de 6 dígitos todos los días, pero pocos comprenden la elegante maquinaria matemática que opera bajo la pantalla. Desde los contadores activados por eventos de RFC 4226 (HOTP) en 2005 hasta las ventanas de intervalos temporales discretos de RFC 6238 (TOTP) en 2011, esta guía examina a fondo el algoritmo de truncamiento dinámico a nivel de bytes, los riesgos de desincronización de contadores, las tolerancias de desfase de reloj y las razones por las cuales TOTP conquistó la Internet moderna.

2FA
Equipo de Seguridad 2FA-Tool
Actualizado en octubre de 2026
Tiempo de lectura estimado: 14 min (más de 2.600 palabras)
RFC 6238 RFC 4226 Truncamiento Dinámico
💡 Conclusiones criptográficas clave (TL;DR)
  • La diferencia fundamental de entrada: HOTP calcula resúmenes criptográficos a partir de un contador monótonamente creciente C, mientras que TOTP sustituye C por un paso de tiempo de época Unix T (TiempoUnixActual / 30).
  • Herencia matemática directa: TOTP es rigurosamente una especialización de HOTP: TOTP(K, Tiempo) = HOTP(K, T). Ambos algoritmos ejecutan exactamente la misma función de truncamiento dinámico (Dynamic Truncation).
  • Factor arquitectónico determinante: HOTP requiere estado persistente (los servidores deben aplicar bloqueos y persistir el avance de los contadores en base de datos tras cada validación). TOTP carece de estado (stateless), lo que permite a los microservicios en la nube validar códigos en clústeres distribuidos y balanceados sin transacciones de escritura centralizadas.
01

Raíces históricas: De tokens físicos propietarios a estándares abiertos web

A principios de la década del 2000, la autenticación de dos factores en el ámbito corporativo estaba monopolizada por llaveros de hardware propietarios, como RSA SecurID. Estos dispositivos cerrados y costosos contenían un oscilador de cristal de cuarzo sincronizado con servidores empresariales propietarios. Si una organización deseaba dotar de seguridad de doble factor a miles de empleados, la adquisición del hardware físico y los costes de licencias comerciales eran prohibitivos.

Con el objetivo de emancipar los esquemas de autenticación de proveedores cautivos, los líderes del sector fundaron el consorcio OATH (Initiative for Open Authentication) para diseñar especificaciones del IETF de acceso libre y libres de regalías, permitiendo a cualquier ingeniero de software implementarlas, auditarlas y desplegarlas sin restricciones:

📜 2005: RFC 4226 (HOTP)

Algoritmo de contraseña de un solo uso basado en HMAC. Orientado inicialmente a microcontroladores de baja potencia con pulsadores mecánicos. Cada pulsación del botón incrementa un contador interno y proyecta un token de 6 dígitos en una pantalla de cristal líquido (LCD).

📜 2011: RFC 6238 (TOTP)

Algoritmo de contraseña de un solo uso basado en tiempo. Diseñado en plena eclosión del smartphone. Al aprovechar la sincronización horaria por red celular mediante el protocolo NTP, TOTP eliminó definitivamente los problemas de desalineación de estado derivados de los pulsadores físicos.

02

HOTP (RFC 4226) y la mecánica de truncamiento dinámico a nivel de bytes

La definición matemática medular de HOTP destaca por su concisión:

HOTP(K, C) = Truncate(HMAC-SHA-1(K, C)) mod 10Dígitos

Desglose de parámetros:

  • K: Clave simétrica secreta compartida (por lo general, una secuencia binaria de 160 bits / 20 bytes decodificada a partir de Base32).
  • C: Contador entero de 8 bytes (64 bits) formateado en orden big-endian.
  • HMAC-SHA-1: Código de autenticación de mensajes basado en hash con clave que produce un resumen criptográfico de 20 bytes (160 bits).

🔍 Cómo convierte el truncamiento dinámico (DT) 20 bytes en 6 dígitos decimales:

Un resumen HMAC-SHA1 contiene 160 bits (20 bytes). Extraer 6 dígitos decimales uniformemente distribuidos requiere un mecanismo de selección determinista y resistente a colisiones, definido en la Sección 5.3 del RFC 4226:

// Paso 1: Cálculo del desplazamiento dinámico (Offset)
Offset = HS[19] & 0x0F
Se extrae el último byte (índice 19) del resumen de 20 bytes. Aplicar una máscara binaria con 0x0F aísla los 4 bits de menor peso, arrojando un número entero estrictamente comprendido entre 0 y 15 (0x0 a 0xF). Esto garantiza que la posterior lectura de 4 bytes consecutivos jamás desborde el búfer de 20 bytes (ya que 15 + 4 = 19).
// Paso 2: Extracción de 4 bytes consecutivos y enmascaramiento
P = ( (HS[Offset] & 0x7F) << 24 ) | ( (HS[Offset+1] & 0xFF) << 16 ) | ( (HS[Offset+2] & 0xFF) << 8 ) | ( HS[Offset+3] & 0xFF )
Se extraen 4 bytes contiguos a partir del índice Offset. La máscara 0x7F pone a cero el bit más significativo (MSB) para suprimir cualquier signo negativo en la representación binaria de CPU de 32/64 bits, asegurando un entero positivo sin signo de 31 bits.
// Paso 3: Aritmética modular para los dígitos finales
OTP = P mod 106 = P mod 1000000
Al aplicar la operación módulo 1.000.000 se extraen los 6 dígitos decimales finales, anteponiendo ceros a la izquierda mediante formato en cadena si el resultado consta de menos dígitos (por ejemplo, 748 se proyecta como "000748").
🧪 Vector de prueba verificado del Apéndice D de RFC 4226:

Tomando como clave secreta la cadena ASCII "12345678901234567890" y un contador C = 0, el resumen HMAC-SHA1 en notación hexadecimal resultante es:

cc 93 cf 18 50 8d 94 93 4c 64 b6 6d 8b fb 87 fb 23 cb 4b 71

1. El byte final es 0x71. Operando 0x71 & 0x0F = 0x01, por tanto Offset = 1.
2. Los bytes desde la posición 1 a la 4 son: 93 cf 18 50. Enmascarando el bit más significativo obtenemos 0x13cf1850, cuyo valor decimal equivalente es 332.339.280.
3. 332339280 mod 1000000 = 339280. ¡El código de autenticación de 6 dígitos resultante es 339280!

03

Evolución de TOTP (RFC 6238): La magia del intervalo temporal

HOTP imponía el reto de mantener el contador del cliente perfectamente sincronizado con el del servidor. En aplicaciones de software, contabilizar pulsaciones físicas introduce constantes fallos por desalineación accidental.

RFC 6238 resolvió esto reemplazando el contador C por un paso temporal discreto T derivado directamente del reloj de época Unix:

T = ⌊ (TiempoUnixActual - T0) / X ⌋
  • TiempoUnixActual: Segundos transcurridos desde el 1 de enero de 1970 a las 00:00:00 UTC (tiempo universal coordinado).
  • T0: Punto de origen de la época de cálculo (establecido por defecto en 0 en todas las especificaciones comerciales).
  • X (Ventana del intervalo temporal): Duración estándar recomendada por la industria de 30 segundos.
  • Función suelo ⌊ ⌋: Para cualquier instante contenido en un intervalo de 30 segundos, T genera idéntico valor. Por ejemplo, entre los segundos de época 1728211200 y 1728211229, T se evalúa con exactitud al mismo entero de 64 bits.

Serialización binaria: Una vez computado el entero T, se empaqueta en un búfer binario big-endian de 8 bytes (idéntico en memoria al contador C de HOTP). De este modo, la ecuación unificada queda expresada como:
TOTP(K, Tiempo) = HOTP(K, T) Esta consistencia matemática demuestra por qué los autenticadores móviles renuevan sus códigos sincrónicamente cada 30 segundos sin necesidad de comunicarse con un servidor central.

Soporte ampliado de RFC 6238 para SHA-256 y SHA-512: Mientras que RFC 4226 limitaba su alcance a HMAC-SHA-1, RFC 6238 extendió formalmente el estándar a HMAC-SHA-256 y HMAC-SHA-512. En HMAC-SHA-256 (resumen de 32 bytes), el desplazamiento dinámico se lee en el byte 31 (HS[31] & 0x0F); en HMAC-SHA-512 (resumen de 64 bytes), en el byte 63 (HS[63] & 0x0F). No obstante, en más del 99,9% de las plataformas mundiales (Google, Microsoft, GitHub, AWS), SHA-1 continúa reinando debido a la compatibilidad universal con apps autenticadoras existentes.
04

Matriz comparativa exhaustiva cara a cara (HOTP vs. TOTP)

Dimensión técnica HOTP (RFC 4226) TOTP (RFC 6238)
Variable de entrada Contador de eventos C (estrictamente incremental) Paso de tiempo T (ventana de época Unix de 30 s)
Vida útil del código Indefinida (válido hasta ser consumido en login) Estricta de 30 segundos (caducidad automática)
Arquitectura de servidor Con estado (escritura atómica en BD por login) Sin estado (verificación autónoma basada en NTP)
Exposición a ataques de repetición Moderada (un token interceptado vale hasta su uso) Mínima (restringida a los segundos restantes de ventana)
Causa principal de error Desincronización de contadores (pulsaciones en vacío) Desfase de reloj (retraso en el reloj del móvil)
Funciones hash soportadas Únicamente HMAC-SHA-1 HMAC-SHA-1, HMAC-SHA-256, HMAC-SHA-512
Adopción en la industria Banca heredada, llaves físicas de accesos especiales 99,9% de servicios web y aplicaciones modernas
05

Soluciones de ingeniería ante desincronización y desfase temporal

En arquitecturas de producción distribuidas, tanto clientes como servidores experimentan desajustes inevitables. Para garantizar alta disponibilidad, los criptógrafos establecieron ventanas de compensación controladas:

⚙️ Mitigación en HOTP: Ventana de verificación prospectiva (Look-Ahead Window, s)

Si un usuario presiona el botón de su token 5 veces sin iniciar sesión, el contador del cliente avanza a C+5 mientras el servidor permanece inmóvil en C.
RFC 4226 establece que, al verificar, el servidor debe evaluar un rango prospectivo comprendido entre [C+1, C+s] (siendo habitual un valor de s=20). Si se encuentra coincidencia, el servidor actualiza de inmediato su contador base a dicha posición.

⏱️ Mitigación en TOTP: Tolerancia al desfase de reloj (Ventana ±1)

Debido a la latencia en redes móviles o a una desviación leve en el reloj del smartphone (por ejemplo, 10 segundos de atraso), los códigos pueden ingresar en un intervalo de tiempo adyacente.
Los servidores en producción comprueban una matriz de 3 pasos temporales: [T-1, T, T+1], expandiendo de manera efectiva la ventana admisible a 90 segundos.

Regla obligatoria contra ataques de repetición (Anti-Replay Rule): A fin de impedir que un atacante reutilice un código válido durante la ventana extendida de 90 segundos, el servidor debe almacenar en caché (por ejemplo, en Redis) el token consumido durante 90 segundos, rechazando cualquier intento sucesivo de envío.
🛡️ Comparación de cadenas en tiempo constante (Defensa contra ataques de temporización):

Cuando el servidor valida si el código remitido por el usuario coincide con el calculado, una comparación de cadenas ingenua (como userOtp === serverOtp) se interrumpe en el primer carácter discrepante. Un atacante con capacidad de medir fluctuaciones microscópicas de tiempo en la respuesta de red puede deducir los dígitos uno por uno. Los backends empresariales exigen algoritmos de comparación en tiempo constante (como crypto.timingSafeEqual en Node.js o hmac.compare_digest en Python) para neutralizar ataques de canal lateral.

06

Por qué TOTP conquistó la Internet moderna

El indiscutible triunfo de TOTP sobre HOTP en el ecosistema digital obedeció a tres pilares de arquitectura fundamentales:

☁️ Escalabilidad sin estado en la nube

En microservicios distribuidos entre múltiples regiones, cualquier nodo con un reloj sincronizado mediante NTP puede autenticar tokens TOTP sin necesidad de efectuar bloqueos de escritura sobre una base de datos centralizada.

📱 Sinergia con el ecosistema móvil

Los teléfonos inteligentes sincronizan su reloj automáticamente mediante antenas de telefonía y redes GPS, eliminando desviaciones temporales sin necesidad de suministrar ni mantener dispositivos de hardware adicionales.

🛡️ Ventana de ataque reducida a 30 segundos

Un código HOTP sigue siendo válido indefinidamente hasta que alguien lo utiliza. Los códigos TOTP expiran en 30 segundos, neutralizando automáticamente registros de depuración filtrados e intercepciones de red pasivas.

07

Preguntas frecuentes (FAQ) sobre TOTP y HOTP

¿Por qué HOTP es vulnerable a la desincronización de contadores? ▼

HOTP incrementa un contador interno C cada vez que se pulsa el botón físico. Si un usuario presiona el token 20 veces sin enviar los códigos generados al servidor, el contador del dispositivo avanza a C+20 mientras que el servidor permanece en C. Si la diferencia supera la ventana de verificación prospectiva (s) configurada en el servidor, los códigos se rechazan permanentemente hasta ejecutar un protocolo de resincronización manual.

¿Es inseguro el uso de SHA-1 en TOTP dadas las colisiones criptográficas conocidas? ▼

No. TOTP utiliza HMAC-SHA1 en lugar de la función de resumen SHA-1 simple. La seguridad de HMAC se basa en las propiedades de función pseudoaleatoria (PRF) del hash, donde las vulnerabilidades de colisión no se traducen en ataques de recuperación de clave o falsificación. Además, los códigos caducan tras 30 segundos, lo que hace inviable cualquier ataque de fuerza bruta fuera de línea tanto computacional como económicamente.

¿Por qué TOTP permite una verificación sin estado (stateless) en el servidor? ▼

En HOTP, el servidor debe escribir y actualizar el contador C en una base de datos centralizada en cada inicio de sesión exitoso, creando cuellos de botella por bloqueos de escritura en clústeres distribuidos. Con TOTP, el paso temporal T se deriva directamente del reloj del sistema, lo que permite a cualquier nodo bajo un balanceador de carga verificar tokens de forma independiente sin escrituras distribuidas.

🧮 Motor RFC 6238 100% en el Cliente

Prueba tu Clave Secreta 2FA en 2FA-Tool

Comprueba cómo tu clave secreta Base32 se transforma en códigos dinámicos de 6 dígitos mediante truncamiento dinámico HMAC-SHA1. 100% fuera de línea en tu navegador.

Abrir Generador en Línea