Validador de contador HOTP (RFC 4226)|Prueba ventanas de desfase ±N en el navegador
Genera códigos HOTP HMAC-SHA-1 a partir de un secreto Base32 y un contador, y comprueba si un código recibido cae dentro de la ventana ±N. Reproduce el comportamiento de RFC 4226 con solo tus datos, sin necesidad de servidor.
💡 Sobre esta herramienta
HOTP (RFC 4226) es un esquema de contraseña de un solo uso cuyo factor móvil es un contador, no el reloj. Es la base de tokens físicos como la ranura OATH-HOTP de Yubico y de códigos basados en contador que respaldan al SMS. Como no necesita sincronización horaria, encaja en dispositivos sin conexión y entornos donde la hora no es fiable.
El problema típico del OTP por contador es la desincronización. El contador del token avanza cada vez que se pulsa el botón, pero el del servidor solo avanza tras un inicio de sesión correcto. Si el usuario pulsa el token de más, ambos se desalinean y los códigos dejan de validar. RFC 4226 lo absorbe con una ventana de anticipación: el servidor recalcula los siguientes valores HOTP, los compara con el recibido y, al coincidir, fija su contador en el valor coincidente + 1.
Esta herramienta muestra todos los códigos de la ventana a la vez. La fila del contador actual se resalta y la fila que coincide con el código recibido aparece en otro color, de modo que puedes razonar hasta qué desfase debería aceptar un servidor, o depurar un token, sin levantar un backend. Es distinta del TOTP basado en tiempo: usa una herramienta TOTP cuando el factor móvil sea el reloj.
🧐 Preguntas frecuentes
¿En qué se diferencia HOTP de TOTP? En el factor móvil. HOTP usa un contador de eventos; TOTP usa el tiempo. Un código HOTP sigue siendo válido hasta que se usa, mientras que uno TOTP caduca solo a los 30–60 segundos. Esta herramienta es solo HOTP.
¿En qué formato va el secreto compartido?
Base32 de RFC 4648 (A–Z y 2–7). Se ignoran espacios y guiones, y el relleno = final es opcional. Cualquier carácter no válido en Base32 produce un error.
¿Qué significa la ventana ±N? El rango de códigos que se comprueba a ambos lados del contador actual. Una N mayor tolera más desfase pero amplía la superficie de fuerza bruta. RFC §7.4 recomienda rechazar todo contador igual o inferior a uno ya aceptado.
¿Qué longitud de dígitos elijo? La longitud del OTP. Google Authenticator usa 6 dígitos; los tokens de Yubico suelen usar 8. Ajústala a la especificación de tu token.
¿Dónde se realiza el cálculo? Todo en tu navegador mediante la Web Crypto API; el secreto compartido que introduces nunca se envía a un servidor.
📚 La truncación dinámica explicada paso a paso
El núcleo de HOTP es la truncación dinámica, y conviene seguirla con calma. La salida de HMAC-SHA-1 mide 20 bytes. Sus últimos 4 bits se leen como un desplazamiento (offset) entre 0 y 15. Desde esa posición se extraen 4 bytes consecutivos y se pone a 0 el bit más alto, obteniendo un entero de 31 bits. Ese paso del bit alto no es decorativo: evita que algunas implementaciones interpreten los bytes como entero con signo y obtengan otro resultado. Por último se toma el resto de dividir ese entero entre 10 elevado al número de dígitos. El Apéndice D de RFC 4226 fija vectores de prueba —el secreto 12345678901234567890 da 755224 en el contador 0 y 287082 en el contador 1— que permiten verificar cada paso. Gracias a que el procedimiento está congelado con esta precisión, un token y un servidor de fabricantes distintos llegan al mismo código, y el posterior TOTP reutilizó la misma truncación sobre un contador derivado del tiempo.