Los usuarios de Internet deben in­tro­du­cir co­n­tra­se­ñas de manera habitual, por ejemplo para iniciar sesión en una pla­ta­fo­r­ma de red social, en una tienda o en una banca online. Las co­n­tra­se­ñas evitan el acceso de terceros a datos sensibles. Sin embargo, muchos usuarios no prestan la atención necesaria, pues los pro­fe­sio­na­les son capaces de descifrar co­n­tra­se­ñas sencillas en cuestión de segundos. Mientras tanto, otros usuarios guardan co­n­tra­se­ñas de buena calidad de manera in­co­rre­c­ta, lo que pro­po­r­cio­na a los de­li­n­cue­n­tes una puerta de entrada. Además, no hay que olvidar los puntos débiles de los servicios en los que se inicia sesión. Si las co­n­tra­se­ñas no se almacenan de manera adecuada, se ponen en peligro los datos de miles de usuarios.

Una po­si­bi­li­dad para reducir el riesgo es la au­te­n­ti­fi­ca­ción de dos factores o au­te­n­ti­fi­ca­ción mu­l­ti­fa­c­tor. En lugar de utilizar una única co­n­tra­se­ña, es necesario in­tro­du­cir como mínimo un elemento más de au­te­n­ti­fi­ca­ción. Los usuarios la reciben a través del sma­r­t­pho­ne o de un token de hardware. Ge­ne­ra­l­me­n­te, los factores adi­cio­na­les se ca­ra­c­te­ri­zan por ser únicos y tener una validez limitada a un breve periodo de tiempo. Es decir, se genera un llamado Time based One time Password. Te ex­pli­ca­mos cómo funciona.

¿Para qué se necesita TOTP?

Por muy seguras que sean las co­n­tra­se­ñas comunes, siempre presentan un in­co­n­ve­nie­n­te: en cuanto alguien más conoce la secuencia de ca­ra­c­te­res, la seguridad des­apa­re­ce. Una posible solución sería cambiar ha­bi­tua­l­me­n­te la co­n­tra­se­ña, pero incluso los usuarios más eje­m­pla­res no van a hacerlo cada hora. TOTP re­pre­se­n­ta la solución: se trata de una co­n­tra­se­ña válida úni­ca­me­n­te durante un breve periodo de tiempo que después caduca. El Grupo de trabajo de in­ge­nie­ría de internet (IETF) publicó en 2011 el algoritmo Time-based One-time Password en el RFC 6238 para pro­po­r­cio­nar una mayor seguridad en Internet.

Estas co­n­tra­se­ñas únicas son es­pe­cia­l­me­n­te populares como parte de una au­te­n­ti­fi­ca­ción mu­l­ti­fa­c­tor. Para ello, en el inicio de sesión en un servicio web los usuarios utilizan en primer lugar su co­n­tra­se­ña personal fija y, de manera adicional, se genera una co­n­tra­se­ña especial para ese proceso de inicio de sesión durante un periodo limitado. El usuario la recibe, p. ej. a través de una app o de un di­s­po­si­ti­vo especial (token).

Si la co­n­tra­se­ña se utiliza una vez o no se utiliza durante un de­te­r­mi­na­do periodo de tiempo, caduca. Por lo tanto, para los cri­mi­na­les es muy co­m­pli­ca­do acceder al segundo factor. Incluso aunque conozcan la co­n­tra­se­ña, tendrán muy pocas po­si­bi­li­da­des de solicitar también el TOTP o no di­s­po­n­drán del tiempo su­fi­cie­n­te para de­s­ci­frar­lo.

¿Cómo funciona el algoritmo Time-based One-time Password?

La base del TOTP es una función hash, es decir, un pro­ce­di­mie­n­to cri­p­to­grá­fi­co. A partir de una co­n­tra­se­ña secreta y de una marca de tiempo se forma una secuencia de ca­ra­c­te­res co­di­fi­ca­da. La co­n­tra­se­ña es conocida tanto para el usuario como para el servidor. La in­di­ca­ción de tiempo se lleva a cabo en tiempo Unix.

Hecho

El tiempo Unix es un valor que indica los segundos tra­n­s­cu­rri­dos desde el 1 de enero de 1970.

TOTP es en realidad la evolución de HOTP, siglas de «HMAC-based One-time Password». TOTP también está basado en el pro­ce­di­mie­n­to HMAC, la operación hash en segundo plano. Tanto el di­s­po­si­ti­vo del usuario como el servidor generan un valor hash a partir de la co­n­tra­se­ña secreta en co­m­bi­na­ción con un contador. Dado que ambos valores son idénticos, la au­te­n­ti­fi­ca­ción funciona.

La función hash en sí no está definida; en la práctica se recurre p. ej. a SHA-1 (como en el caso de Google Au­the­n­ti­ca­tor), que genera un valor hash con una longitud de 160 bits. Para si­m­pli­fi­car, este valor se acorta por medio de una función de co­m­pre­sión. Al final se cuenta, por ejemplo, con un número de seis cifras que el usuario puede in­tro­du­cir fá­ci­l­me­n­te al iniciar sesión en el servicio web.

Nota

En el caso de los tokens, la co­n­tra­se­ña secreta está anclada en el di­s­po­si­ti­vo y a menudo el usuario no sabe cuál es. Si este no es el caso, la SecretKey se deberá guardar en un sitio seguro, pre­fe­ri­ble­me­n­te offline y, si es posible, incluso impresa y al­ma­ce­na­da en un lugar protegido. Si esta co­n­tra­se­ña se pierde, no es posible iniciar sesión en el servicio.

Como segundo co­m­po­ne­n­te de la función, HOTP está basado en un contador que el servidor y el usuario comparten. El problema en este caso es que la co­n­tra­se­ña que se genera es válida hasta que se utiliza. TOTP restringe este hecho: el código generado solo se puede utilizar dentro de un periodo de tiempo de­te­r­mi­na­do. Pero ¿cómo funciona?

Hay tres fórmulas re­le­va­n­tes para el algoritmo Time-based-One-time:

TOTP = HOTP(SecretKey,Cu­rre­n­t­Ti­me)

Esta sencilla fórmula se limita a es­pe­ci­fi­car que TOTP es un pro­ce­di­mie­n­to HOTP con dos pa­rá­me­tros, SecretKey y Cu­rre­n­t­Ti­me:

  • SecretKey: co­n­tra­se­ña creada de manera aleatoria conocida tanto por el servidor como por el cliente.
  • Cu­rre­n­t­Ti­me: momento actual en tiempo Unix.

No obstante, la in­di­ca­ción del tiempo varía cada segundo. Y un segundo no es su­fi­cie­n­te para tra­n­s­mi­tir el código a la apli­ca­ción. Es decir, el TOTP ya no sería válido pasado un segundo, puesto que el servidor ya habría generado un nuevo valor hash. Por este motivo, se recurre a una fórmula adicional:

Cu­rre­n­t­Ti­me = floor((unixtime(now) – unixtime(T0))/T1)

El parámetro Cu­rre­n­t­Ti­me se define por lo tanto de la siguiente manera:

  • unixtime(now): momento actual en tiempo Unix.
  • unixtime(T0): tiempo Unix en el momento T0 a partir del que se cuenta, en la mayoría de los casos es el 01.01.1970 a me­dia­no­che (= 0).
  • T1: intervalo en el que el TOTP debe ser válido, ge­ne­ra­l­me­n­te 30 segundos.
  • floor: función de redondeo para convertir el valor calculado en un número entero.
Nota

En teoría, también se puede se­le­c­cio­nar otro valor diferente a 0 para T0. Lo único im­po­r­ta­n­te es que el cliente y el servidor se­le­c­cio­nen el mismo valor.

La división y el redondeo generan el efecto de que el resultado varía en in­te­r­va­los.

A co­n­ti­nua­ción, el valor hash generado se acorta para que resulte más fácil para el usuario:

Result = TOTPmod10d

Con el cálculo Módulo se genera una suma de ve­ri­fi­ca­ción:

  • mod 10: módulo con divisor 10
  • d: número de cifras que el TOTP debe tener

De esta forma, la base 10 se eleva a la potencia de las cifras que debe tener el código, se divide el TOTP por este valor y se extrae el resto.

El cálculo de TOTP en un ejemplo

Su­po­n­ga­mos que se desea crear un TOTP con una validez de 30 segundos. De esta forma ya podemos calcular el Cu­rre­n­t­Ti­me e ide­n­ti­fi­car cómo se va a ga­ra­n­ti­zar el periodo de validez. A modo de unixtime(now) tomamos 1548322860, esto es, el 24.01.2019 a las 10:41 h. Si dividimos esta cifra entre 30, obtenemos exac­ta­me­n­te 51610762. Dado que ya se trata de un número entero, tras el redondeo también se obtiene este resultado. Si ahora ajustamos la hora actual 15 segundos más tarde, es decir, 1548322875, tras la división obtenemos 51610762,5 como resultado. También se redondea a 51610762. El Cu­rre­n­t­Ti­me permanece por lo tanto igual. En la siguiente tabla se puede observar que, al cabo de 30 segundos, se genera un nuevo valor:

unixtime(now) unixtime(now)/30 floor(unixtime(now)/30)
1548322857 51610761,9000 51610761
1548322858 51610761,9333 51610761
1548322859 51610761,9667 51610761
1548322860 51610762,0000 51610762
1548322861 51610762,0333 51610762
1548322862 51610762,0667 51610762
1548322863 51610762,1000 51610762
1548322864 51610762,1333 51610762
1548322865 51610762,1667 51610762
1548322866 51610762,2000 51610762
1548322867 51610762,2333 51610762
1548322868 51610762,2667 51610762
1548322869 51610762,3000 51610762
1548322870 51610762,3333 51610762
1548322871 51610762,3667 51610762
1548322872 51610762,4000 51610762
1548322873 51610762,4333 51610762
1548322874 51610762,4667 51610762
1548322875 51610762,5000 51610762
1548322876 51610762,5333 51610762
1548322877 51610762,5667 51610762
1548322878 51610762,6000 51610762
1548322879 51610762,6333 51610762
1548322880 51610762,6667 51610762
1548322881 51610762,7000 51610762
1548322882 51610762,7333 51610762
1548322883 51610762,7667 51610762
1548322884 51610762,8000 51610762
1548322885 51610762,8333 51610762
1548322886 51610762,8667 51610762
1548322887 51610762,9000 51610762
1548322888 51610762,9333 51610762
1548322889 51610762,9667 51610762
1548322890 51610763,0000 51610763
1548322891 51610763,0333 51610763

El Cu­rre­n­t­Ti­me queda por lo tanto fijado (51610762). La SecretKey se obtiene por medio de un generador de co­n­tra­se­ñas: >cHSB_UQ#O5m;~b

HMAC con SHA-1 forma un valor hash (en notación he­xa­de­ci­mal) a partir de la co­n­tra­se­ña y la hora: c0 62 37 94 dd 37 7a 3a f0 91 22 08 1f 21 6f 9b 17 4b 17 45. Este valor de 160 bits o 20 bytes de largo se reduce a 31 bits por medio de la de­no­mi­na­da dynamic tru­n­ca­tion. Para ello, se co­n­si­de­ran en primer lugar los últimos 4 bits, es decir, la cifra 0x5, que también se escribe como 5 en notación decimal. Esto se co­rre­s­po­n­de con el valor de de­s­pla­za­mie­n­to de la dynamic tru­n­ca­tion y significa que, a partir del byte con el índice 5 (desde la izquierda co­me­n­za­n­do por 0), se extraen cuatro bytes: 0x377a3af0. En este caso, el valor comienza con un bit que está en 0. Si este no fuera el caso, se mo­di­fi­ca­rá co­rre­s­po­n­die­n­te­me­n­te. Por lo tanto, el valor con una longitud de 31 bits es también 0x377a3af0 o 930757360.

Para reducir esta secuencia de nueve cifras a seis, se utiliza una operación módulo y, en caso necesario, se rellena a la izquierda con ceros: 930757360 mod (106) = 757360. Este es el TOTP que tendrá validez durante 30 segundos. En co­m­bi­na­ción con otro factor se consigue un pro­ce­di­mie­n­to de inicio de sesión bastante seguro.

Ir al menú principal