Las mejores contraseñas nunca salen de tu dispositivo
Las contraseñas son un problema por razones que ignoran la mayoría de las personas que las usan. Si pierdes el control de tu contraseña, la seguridad quedará expuesta con total seguridad, sin importar su complejidad o lo difícil que sea de adivinar.
La mayoría de los lectores admitirán de inmediato las dificultades para recordar y administrar contraseñas, sobre todo porque los requisitos de estas son cada vez más complejos. Afortunadamente, existen grandes paquetes de software y complementos para el navegador que ayudan a administrarlas. Sin embargo, muchos se sorprenderán al saber que los problemas, que son consecuencia de la falta de seguridad inherente de las contraseñas, son mucho más graves de lo que generalmente se cree.
Podrías decirnos: "¡Pero las contraseñas siempre se almacenan en formato encriptado!" y no te equivocas, pero es una afirmación incompleta. La verdad es que incluso una contraseña encriptada puede descifrarse, aunque (por suerte) no sin dificultades cuando se cifran correctamente. Un problema cada vez más acuciante radica en la naturaleza de las propias contraseñas: para utilizar una contraseña, directamente, esta debe administrarse sin cifrar.
"¡Pero mi contraseña se transmite de forma segura mediante HTTPS!". Es cierto.
"¡Sé que el servidor almacena mi contraseña en forma encriptada, segura, para que nadie pueda acceder a ella!", podrías asegurar. Bueno, en este caso estás depositando mucha confianza en el servidor. Aun así, digamos que sí, es verdad.
Sin embargo, queda una limitación: la brecha en el uso de las contraseñas de extremo a extremo. Ten en cuenta que una vez que un servidor recibe una contraseña, esta tiene que leerse y procesarse mientras se transmite y procesa de forma segura. Sí, ¡como texto sin formato!
Y lo que es peor, muchos están acostumbrados a pensar en software, lo que hace que sea más fácil olvidarse de la vulnerabilidad del hardware. Esto significa que, aunque el software sea de alguna manera de confianza, la contraseña debe en algún momento residir en la memoria. La contraseña se debe transmitir en algún momento a la CPU a través de un bus de datos compartido. Este proceso proporciona vectores de ataque a los observadores de muchas formas. No hay duda de que estos vectores de ataque son menos probables que los que presentan la transmisión y el almacenamiento permanente, pero no son menos graves (vulnerabilidades recientes de la CPU como Spectre y Meltdown deberían servir como un claro recordatorio).
La única forma de solucionar este problema es eliminar las contraseñas por completo. ¡Hay esperanza! Las comunidades de investigación y del sector privado están trabajando duro para lograrlo. Están surgiendo nuevos estándares que están avanzando. Lamentablemente, las contraseñas son tan ubicuas que va a llevar mucho tiempo alcanzar un acuerdo y sustituirlas por nuevos estándares y tecnología.
En Cloudflare, nos hemos preguntado si hay algo que podamos hacer ahora, de forma inminente. El análisis exhaustivo sobre OPAQUE que abordamos hoy es una posible respuesta. OPAQUE es uno de los muchos ejemplos de sistemas que permiten que una contraseña sea útil sin que pierdas el poder sobre ella. A nadie le gustan las contraseñas, pero mientras se usen, al menos podemos asegurarnos de que nunca se revelen.
Somos los primeros en admitir que las contraseñas son molestas: son difíciles de recordar, tediosas de escribir y bastante poco seguras. Las iniciativas para reducir o reemplazar las contraseñas son prometedoras. Por ejemplo, WebAuthn es un estándar de autenticación web basado principalmente en criptografía de clave pública que utiliza tokens de hardware (o de software). Aun así, y por muy frustrante que sea, las contraseñas siguen siendo el mecanismo de autenticación por excelencia. El hecho de que no podamos librarnos de ellas puede obedecer a su facilidad de implementación, a la confianza que ofrecen a los usuarios o su ubicuidad. Sea cual sea el motivo, nuestra meta es que la autenticación por contraseñas sea lo más segura posible mientras se siga empleando este método.
En este sentido OPAQUE, de Cloudflare, es un protocolo criptográfico que resuelve uno de los problemas de seguridad más evidentes de la autenticación por contraseña en la web: aunque están protegidas en tránsito por el protocolo HTTPS, los servidores las gestionan en texto sin formato para verificar su exactitud. La utilización de contraseñas de texto sin formato es peligrosa, ya que registrarlas accidentalmente o almacenarlas en caché podría provocar un fallo de seguridad catastrófico. El objetivo del proyecto, más que abogar por la adopción de un protocolo en particular, es demostrar que OPAQUE es una opción viable entre muchas otras para la autenticación.
Autenticación web 101: Contraseña mediante protocolo TLS
¿Qué ocurre cuando escribes una contraseña en la web? El sitio web tiene que verificar que la contraseña que escribiste sea la misma que la que utilizaste originalmente en el sitio. Pero ¿cómo funciona esta comprobación?
Por lo general, tu nombre de usuario y contraseña se envían a un servidor. El servidor comprueba a continuación si la contraseña que tiene registrada para tu nombre de usuario coincide con la contraseña que facilitaste. No cabe duda de que para evitar que un atacante intercepte tu contraseña mientras navegas por Internet, tu conexión al servidor debe estar encriptada a través de HTTPS (HTTP mediante TLS).
A pesar del uso del protocolo HTTPS, sigue habiendo un problema evidente en esta dinámica: el servidor debe almacenar una representación de su contraseña en algún lugar. Los servidores son difíciles de proteger y los fallos de seguridad son demasiado habituales. La filtración de esta representación puede causar graves problemas de seguridad. (Puedes consultar los últimos fallos de seguridad en el siguiente enlace: https://haveibeenpwned.com/).
Para que estas filtraciones sean menos devastadoras, los servidores suelen aplicar una función hash a las contraseñas de los usuarios. Una función hash asigna cada contraseña a un valor de aspecto aleatorio único. Es fácil aplicar el hash a una contraseña, pero es casi imposible revertir la función y recuperar la contraseña. (Dicho esto, cualquiera puede adivinar una contraseña, aplicar la función hash y comprobar si el resultado es el mismo).
Con el hash aplicado a contraseñas, las contraseñas de texto sin formato ya no se almacenan en los servidores. Un atacante que roba una base de datos de contraseñas ya no tiene acceso instantáneo a las mismas. En cambio, el atacante necesita aplicar el hash a muchas contraseñas posibles y comparar los resultados con los hashes robados.
Por desgracia, si solo aplicamos el hash a las contraseñas, los atacantes pueden descargar tablas rainbow, o tablas arco iris precalculadas, que contienen hash de billones de posibles contraseñas y recuperar casi instantáneamente las contraseñas de texto sin formato. (Consulta https://project-rainbowcrack.com/table.htm para obtener una lista de algunas tablas rainbow).
Teniendo esto en cuenta, una buena y exhaustiva estrategia de defensa es añadir un salt al hash, donde el salt es un valor aleatorio que se añade a la contraseña, siendo el servidor quien encripta la contraseña y el salt. El servidor también guarda el salt al lado del nombre de usuario, por lo que el usuario ni lo ve ni necesita enviarlo. Cuando el usuario envía una contraseña, el servidor vuelve a calcular esta función hash utilizando el salt. Por tanto, un atacante que roba datos de contraseñas, es decir, las representaciones de contraseñas y los valores salt, tiene que descifrar una por una las contraseñas comunes y aplicar la función a cada una de ellas. Las tablas rainbow existentes no le servirán de ayuda porque no tienen en cuenta los valores salt, por lo que el atacante debe crear una nueva tabla rainbow ¡para cada usuario!
Esto (con suerte) ralentiza el ataque lo suficiente como para que el servicio informe a los usuarios del fallo de seguridad, de modo que puedan cambiar sus contraseñas. Además, la efectividad de los hashes con salt se puede reforzar aplicando un hash muchas veces para ralentizar los ataques. (Consulta https://blog.cloudflare.com/keeping-passwords-safe-by-staying-up-to-date/ para obtener más información).
Estas dos estrategias de mitigación, el cifrado de la contraseña en tránsito y el almacenamiento de hashes reforzados con salt, son las mejores prácticas de hoy en día.
Una gran brecha de seguridad sigue abierta. Una contraseña mediante protocolo TLS (como lo llamaremos) requiere que envíes tu contraseña de texto sin formato al servidor cada vez que inicias sesión porque el servidor debe ver tu contraseña para verificarla con las contraseñas registradas. Incluso un servidor bien intencionado podría almacenar accidentalmente la información en caché o registrar tu intento o intentos de acceso con la contraseña, o dañarse en el curso de la verificación de esta. (Por ejemplo, Facebook se dio cuenta en 2019 de que había estado almacenando sin querer millones de contraseñas de texto sin formato de sus usuarios). En teoría, los servidores nunca deberían ver una contraseña de texto sin formato.
Pero esto es como una encrucijada: ¿cómo puedes verificar una contraseña si no la ves? Con OPAQUE, un protocolo de intercambio de claves autenticadas por contraseña (PAKE) que acredita conocer una contraseña y deriva una clave secreta simultáneamente. Antes de describir OPAQUE en detalle, primero resumiremos las funcionalidades de PAKE en general.
Pruebas de contraseña con intercambio de claves autenticadas con contraseña
El intercambio de claves autenticadas por contraseña (PAKE) fue propuesto por Bellovin y Merrit[1] en 1992, con el objetivo inicial de permitir la autenticación de contraseñas sin la posibilidad de ataques de diccionario basados en datos transmitidos a través de un canal inseguro.
Básicamente, el PAKE, plano o simétrico, es un protocolo criptográfico que permite a dos partes que comparten solo una contraseña establecer una clave secreta compartida y segura. Los objetivos del PAKE son:
- Las claves secretas coincidirán si las contraseñas coinciden y, en caso contrario, serán aleatorias.
- Los participantes no necesitan confiar en terceros (particularmente, en ninguna infraestructura de clave pública).
- La clave secreta resultante no la conoce nadie ajeno al protocolo, ni siquiera aquellos que conocen la contraseña.
- El protocolo no revela la contraseña de ninguna de las partes al otro (a menos que las contraseñas coincidan) ni tampoco a los intrusos.
En resumen, la única forma de atacar con éxito el protocolo es adivinar la contraseña correctamente mientras se participa en el protocolo. (Afortunadamente, estos ataques se pueden neutralizar en su mayoría mediante rate-limiting, es decir, impidiendo que un usuario inicie sesión después de un cierto número de intentos de contraseña incorrectos).
A partir de estos requisitos, se entiende que la contraseña mediante protocolo TLS claramente no es un PAKE, porque:
- Depende de WebPKI, que confía en terceras partes denominadas Autoridades de certificación (consulta https://blog.cloudflare.com/introducing-certificate-transparency-and-nimbus/ para saber más sobre WebPKI y algunas de sus limitaciones).
- La contraseña del usuario se revela al servidor.
- La contraseña mediante el protocolo TLS no proporciona al usuario ninguna garantía de que el servidor conozca su contraseña o un derivado de ella: un servidor podría aceptar cualquier dato del usuario sin ningún tipo de verificación.
Dicho esto, las prestaciones de seguridad del PAKE plano son inferiores a las de la contraseña mediante protocolo TLS, simplemente porque requiere que el servidor almacene contraseñas en texto sin formato. Necesitamos un PAKE que permita al servidor almacenar hashes con salt si queremos superar la práctica actual.
La mejora con respecto al PAKE plano es lo que se conoce como PAKE asimétrico (aPAKE) porque solo el cliente conoce la contraseña y el servidor conoce un hash de contraseña. Un aPAKE tiene además de las cuatro propiedades de un PAKE, una más:
5) Un atacante que roba datos de contraseña almacenados en el servidor debe realizar un ataque de diccionario para recuperar la contraseña.
Sin embargo, el problema con la mayoría de los protocolos aPAKE existentes es que no permiten un hash con salt (o si lo hacen, requieren que el salt se transmita al usuario, lo que significa que el atacante tiene acceso al salt de antemano y puede comenzar a calcular una tabla rainbow para el usuario antes de robar cualquier dato). Por lo tanto, nos gustaría actualizar la propiedad de seguridad de la siguiente manera:
5*) Un atacante que roba datos de contraseña almacenados en el servidor debe realizar un ataque de diccionario por usuario para recuperar la contraseña después de que los datos se vean comprometidos.
OPAQUE es el primer protocolo aPAKE con prueba formal de seguridad que tiene esta propiedad: permite un salt completamente secreto.