Cómo funcionan los códigos TOTP
Un código TOTP es un número de 6 dígitos que una aplicación de autenticación y un servidor calculan cada uno por su cuenta, a partir de las mismas dos entradas: una clave secreta compartida y la hora actual, dividida en ventanas de 30 segundos. El código en sí nunca se transmite durante la configuración y no lleva información sobre el secreto, y aun así ambas partes llegan a los mismos dígitos, porque TOTP no es magia ni azar: es un algoritmo publicado (RFC 6238) aplicado a las mismas entradas. Este artículo recorre el cálculo de principio a fin, explica por qué un «código incorrecto» es casi siempre un problema de reloj y repasa las reglas de manejo que deciden si tu segundo factor sigue siendo un segundo factor. Puedes ejecutar cada paso tú mismo en el generador TOTP, que calcula los códigos localmente en tu navegador.
Dos entradas, un código: el secreto y el reloj
Cuando activas la autenticación en dos factores, el servicio genera un secreto aleatorio —normalmente 20 bytes, mostrados como una cadena de caracteres Base32 y, por comodidad, codificados en un código QR—. Ese secreto se guarda en exactamente dos sitios: la base de datos del servicio y tu autenticador. A partir de ese momento, iniciar sesión es un cálculo sincronizado. Ambas partes toman la hora Unix actual, la dividen por el paso de tiempo (30 segundos en casi todos los servicios) y alimentan el contador resultante, junto con el secreto, a una función hash. Quien presente la salida coincidente es tratado como poseedor del secreto.
La elegancia del diseño está en lo que deja fuera. No hay desafío que enviar, ni código que entregar, ni ida y vuelta por la red, ni nada por inicio de sesión que un atacante pueda interceptar: la propiedad de «un solo uso» viene del reloj, porque el contador cambia cada 30 segundos y las salidas viejas dejan de valer. También significa que el sistema tiene exactamente dos cosas que pueden fallar: el secreto y la hora. Casi todos los fallos de TOTP, y todos los robos de TOTP, se remontan a una de esas dos.
El cálculo, paso a paso
El contador se escribe primero como un entero big-endian de 8 bytes, una codificación de ancho fijo en la que ambas partes están de acuerdo. Ese mensaje pasa entonces por HMAC con el secreto como clave, usando el hash acordado: SHA-1 por defecto, con SHA-256 y SHA-512 definidos para los servicios que los elijan. HMAC es una construcción con clave, no un hash simple: hashear solo el contador permitiría a cualquiera con el algoritmo reproducir los códigos, mientras que las salidas de HMAC son infalsificables sin el secreto y no pueden invertirse para recuperarlo.
Un resumen tiene 20 bytes o más; un campo de inicio de sesión quiere 6 dígitos. El puente es el truncamiento dinámico: el último medio byte del resumen selecciona un desplazamiento, se leen cuatro bytes desde ese desplazamiento con el bit superior enmascarado (para evitar ambigüedad de signo) y el número de 31 bits resultante se reduce módulo 10^dígitos —un millón para los seis dígitos estándar—, rellenado con ceros a la izquierda. Ese es el código que escribes. La siguiente ventana recalcula desde cero; no hay cadena que una un código con el siguiente, y por eso un código fotografiado no vale nada treinta segundos después.
Cuando el código es rechazado: suele ser el reloj
Como el contador se deriva del tiempo, el generador y el servidor deben coincidir en cuál es la ventana actual de 30 segundos. La mayoría de los servidores lo suaviza aceptando también las ventanas vecinas —un paso a cada lado—, lo que absorbe en silencio pequeñas desviaciones. Más allá de eso, todo código es incorrecto, por correcto que sea el secreto, y el fallo se ve idéntico a un dígito mal tecleado: un rechazo seco, sin ninguna pista sobre qué entrada discrepó.
Así que el primer diagnóstico ante un autenticador que falla de repente nunca es el secreto; es el reloj del dispositivo que genera los códigos. Una hora ajustada a mano, una batería CMOS moribunda, un teléfono que pasó un vuelo en el modo de zona horaria equivocado: cualquiera de ellos puede desviar el dispositivo un minuto o más. Nuestro generador TOTP muestra una tarjeta de reloj en vivo y compara tu dispositivo con la hora del servidor exactamente por esto. Activa la fecha y hora automáticas y los códigos casi siempre vuelven a funcionar, sin reinicio, sin secreto nuevo, sin ticket de soporte.
El secreto es todo el juego
Quitada la ceremonia, la seguridad de TOTP es un solo hecho: quien tenga el secreto tiene el segundo factor, para siempre, desde cualquier lugar, sin forma de que el servicio distinga sus códigos de los tuyos. El código QR que escaneas al configurar no es una imagen de un código: es el secreto mismo, más la etiqueta de la cuenta y los parámetros, formateado como un URI otpauth://. Una captura de pantalla de él es una copia permanente de tu segundo factor.
Por eso las reglas de manejo son más estrictas que para las contraseñas. Una contraseña la verifica el servidor y puede guardarse con hash; un secreto TOTP debe poder recuperarse en bruto por ambas partes, así que no se puede disolver con un hash, y cada copia es una copia viva. Guarda la copia maestra en tu autenticador o en un gestor de contraseñas cifrado. Nunca lo escribas en un sitio web que genera códigos en su servidor —le has entregado a un desconocido una llave permanente— y nunca lo pegues en un chat, como explica la siguiente sección.
Por qué el secreto nunca debe ir en un chat
Pegar un secreto 2FA en un chat —una conversación de soporte, un canal de equipo, un asistente de IA— parece inofensivo porque la cadena parece un galimatías y la conversación parece privada. No es ninguna de las dos cosas. Los chats se registran, se conservan, se sincronizan con cada dispositivo de la cuenta, se pueden buscar y se procesan en servidores que no controlas; los chats de IA añaden a la lista las canalizaciones de entrenamiento y la retención prolongada. En el momento en que el secreto aterriza ahí, tu segundo factor existe en sistemas diseñados para guardar e indexar texto.
El patrón seguro es que el secreto solo debería existir en tres tipos de lugares: la base de datos del servicio, tu autenticador o gestor de contraseñas, y el cálculo local en un dispositivo que controlas —que es como está construido el generador TOTP de este sitio, con el secreto guardado solo en la memoria de la página y destruido al recargar—. Si un secreto ya se pegó donde no debía, trátalo como quemado: desactiva y vuelve a activar la doble autenticación en el servicio para acuñar uno nuevo, reenrola tu autenticador y, ya que estás, comprueba la propia contraseña en la comprobación de filtraciones de contraseñas.
Lo que TOTP no detiene
TOTP derrota el robo de contraseñas, el relleno de credenciales y las filtraciones de bases de datos: saber tu contraseña ya no basta. No derrota el phishing en tiempo real. Una página de inicio de sesión falsa que reenvía tus credenciales al servicio real y te pide el código puede pasar el código dentro de su ventana de 30 segundos: el código prueba la posesión del secreto, no que estés hablando con el sitio genuino. El robo de la cookie de sesión lo elude con la misma completitud, porque el código solo se comprueba una vez.
Por eso las passkeys y las llaves de seguridad de hardware están desplazando a TOTP en la gama alta: vinculan la prueba al origen del sitio, sin dejar nada tecleable que un relevo pueda robar. TOTP sigue siendo una base sólida y universal —muy superior a los códigos SMS, que heredan las debilidades de la red telefónica—, pero debe desplegarse con los ojos abiertos: protege el secreto como una llave maestra, guarda los códigos de respaldo en otro sitio, mantén honesto tu reloj y prefiere una passkey siempre que el servicio la ofrezca.