La criptografía que utilizamos a diario tiene fecha de caducidad. No es fácil prever cuándo, pero se espera que en un plazo de unos 15 o 40 años se habrá creado un ordenador cuántico lo suficientemente potente para desencriptar prácticamente cualquier dato encriptado del Internet actual.
Afortunadamente, hay una solución: la criptografía poscuántica (PQ) se ha diseñado para proteger contra la amenaza de los ordenadores cuánticos. Hace apenas 3 meses, en julio de 2022, tras una competición mundial de 6 años de duración, el National Institute of Standards and Technology (NIST) de EE. UU., conocido por las encriptaciones AES y SHA2, anunció qué criptografía poscuántica estandarizarán. NIST tiene previsto publicar los estándares finales en 2024, pero queremos contribuir a impulsar la adopción temprana de la criptografía poscuántica.
A partir de hoy, como un servicio beta, todos los sitios web y las API servidos a través de Cloudflare admiten el acuerdo de claves híbridas poscuánticas. Este servicio está activado de forma predeterminada1, no es necesario suscribirse. Esto significa que si tu navegador/aplicación lo admite, la conexión a nuestra red también está protegida contra cualquier futuro ordenador cuántico.
Ofrecemos esta criptografía poscuántica de forma gratuita: creemos que la seguridad poscuántica debe ser la nueva base de Internet.
Con la llegada de los ordenadores cuánticos en un futuro cercano, la implementación de la criptografía poscuántica parece evidente, pero no está exenta de riesgos. Para empezar, es una criptografía nueva. Incluso con años de estudios, no es inconcebible que aún se pudiera descubrir un ataque catastrófico. Por eso, estamos implementando híbridos: una combinación de claves ya probadas junto con una clave nueva que añade seguridad poscuántica.
Lo que nos preocupa más son las cuestiones puramente prácticas. Aunque los protocolos utilizados para proteger Internet están diseñados para permitir este tipo de transiciones fluidas, en realidad hay mucho código que puede causar problemas. Intentar crear una conexión segura poscuántica podría fallar por muchas razones. Por ejemplo, un intermediario podría no entender correctamente las claves poscuánticas más grandes, o debido a otras razones que aún debemos contemplar, ya que estos acuerdos de claves poscuánticas son completamente nuevos. Por ello, creemos que es importante implementar pronto la criptografía poscuántica, para que junto con los navegadores y otros clientes podamos encontrar y resolver estos problemas.
En esta entrada del blog, explicaremos cómo TLS, el protocolo utilizado para proteger Internet, está diseñado para permitir una migración fluida y segura de la criptografía que utiliza. A continuación, comentaremos los detalles técnicos de la criptografía poscuántica que hemos implementado, y cómo, en la práctica, esta migración podría no resultar tan fluida. Para finalizar, explicaremos cómo podemos crear una red de Internet poscuántica, más segura y mejor para todos si nos ayudas a probar esta nueva generación de criptografía.
TLS: Transport Layer Security
Cuando navegas por un sitio web utilizando una conexión segura, ya sea con HTTP/1.1 o QUIC, utilizas el protocolo TLS (Transport Layer Security) subyacente. En la actualidad, hay dos versiones principales de TLS que se utilizan habitualmente: el nuevo TLS 1.3 (aprox. el 90 %) y la anterior TLS 1.2. (aprox. el 10 %) cuyo uso está decayendo.
TLS 1.3 es una mejora importante respecto a TLS 1.2: es más rápido, seguro, sencillo y flexible justo allí donde se requiere. Esto facilita añadir la seguridad poscuántica a TLS 1.3 respecto a TLS 1.2. Por ahora, lo dejaremos así: solo hemos añadido soporte poscuántico a TLS 1.3.
Así, ¿qué hace TLS? El objetivo es configurar una conexión entre un navegador y un sitio web, para lograr
Confidencialidad e integridad: nadie puede leer ni manipular indebidamente los datos sin ser detectado.
Autenticidad: sabes que estás conectado al sitio web adecuado; no a un impostor.
Herramientas esenciales: AEAD, acuerdo de claves y firmas
Para lograr este objetivo, se utilizan tres tipos distintos de criptografía en TLS.
La encriptación simétrica o, más exactamente, la encriptación autenticada con datos asociados (AEAD), es el mecanismo principal de la criptografía: se utiliza para garantizar la confidencialidad y la integridad. Este tipo de encriptación es sencillo: se utiliza una sola clave para encriptar y desencriptar los datos. Sin la clave adecuada, no puedes desencriptar los datos y cualquier manipulación indebida de los datos encriptados generará un error al intentar la desencriptación.
En la actualidad, en TLS 1.3 se utilizan habitualmente ChaCha20-Poly1305 y AES128-GCM. ¿Y qué pasa con los ataques cuánticos? A primera vista, parece que necesitamos pasar a claves simétricas de 256 bits para defendernos contra el algoritmo de Grover. Sin embargo, en la práctica este algoritmo no paraleliza bien, por lo que las AEAD implementadas actualmente ya nos sirven.
Por lo tanto, si acordamos una clave compartida para utilizar con la encriptación simétrica, lo habremos logrado. Pero, ¿cómo puedo obtener una clave compartida? No puedes simplemente elegir una clave y enviarla al servidor: cualquier persona que estuviera a la escucha también la conocería. Se podría pensar que es una tarea imposible, pero aquí es donde la magia de la criptografía asimétrica nos echa una mano:
Un acuerdo de claves, también denominado intercambio de claves o distribución de claves, es un protocolo criptográfico con el que dos partes pueden acordar una clave compartida sin que una persona no deseada pueda descubrirla. Hoy, el protocolo X25519 Elliptic Curve Diffie–Hellman (ECDH) es el estándar utilizado en TLS 1.3. La seguridad de X25519 se basa en el problema de logaritmo discreto para curvas elípticas, que es vulnerable a ataques cuánticos, ya que un ordenador cuántico criptográficamente relevante lo puede resolver fácilmente utilizando el algoritmo de Shor. La solución es utilizar un acuerdo de claves poscuánticas, como por ejemplo, Kyber.
Un acuerdo de claves solo protege contra un atacante pasivo. Un atacante activo, que puede interceptar y modificar mensajes (MitM), puede establecer claves compartidas con el servidor y con el navegador, volviendo a encriptar todos los datos que pasan. Para resolver este problema, necesitamos el componente final de la criptografía.
Con un algoritmo de firma digital, como por ejemplo RSA o ECDSA, hay dos claves: una clave pública y una clave privada. Solo con la clave privada podemos crear una firma para un mensaje. Cualquier persona con la clave pública correspondiente puede comprobar si una firma es realmente válida para un mensaje específico. Estas firmas digitales son el ADN de los certificados TLS que se utilizan para autenticar los sitios web.Tanto RSA como ECDSA son vulnerables a ataques cuánticos. Aún no los hemos reemplazado por firmas poscuánticas. El motivo es que esta autenticación es menos urgente: solo necesitamos haberlas reemplazado cuando se haya creado un ordenador cuántico lo suficientemente grande, mientras que los datos protegidos hoy mediante un acuerdo de claves vulnerable se pueden almacenar y desencriptar en el futuro. Aunque nos queda tiempo, la implementación de la autenticación poscuántica representará un desafío considerable.
Así, ¿cómo se combinan estas herramientas esenciales para crear TLS?
Descripción general de alto nivel de TLS 1.3
Una conexión TLS se inicia con un protocolo de enlace que se utiliza para autenticar el servidor y obtener una clave compartida. El navegador (cliente) empieza enviando un mensaje ClientHello que contiene una lista de AEAD, algoritmos de firma, y los métodos de acuerdo de claves que admite. Para eliminar un viaje de ida y vuelta, se permite que el cliente pronostique qué admite el servidor e inicie el acuerdo de claves enviando una o más comparticiones de clave de cliente. La previsión puede ser correcta (a la izquierda del diagrama siguiente) o el cliente debe volver a intentarlo (a la derecha).
Flujo de protocolo para TLS 1.3 autenticado por servidor con una compartición de clave de cliente admitida a la izquierda y un HelloRetryRequest a la derecha.
Acuerdo de claves
Antes de que expliquemos el resto de esta interacción, profundicemos en el acuerdo de claves: ¿Qué es una clave compartida? Los acuerdos de claves para Kyber y X25519 funcionan de forma distinta: el primero es un mecanismo de encapsulación de clave (KEM), mientras que el segundo es un acuerdo de estilo Diffie–Hellman (DH). Este es más flexible, pero para TLS no supone ninguna diferencia.
La forma de un acuerdo de claves KEM y Diffie–Hellman en TLS es la misma.
En ambos casos, el cliente envía una compartición de clave de cliente al servidor. Este, a partir de esta compartición de clave de cliente, genera la clave compartida. A continuación, el servidor devuelve una compartición de clave de servidor con la que el cliente también puede calcular la clave compartida.
Volviendo al flujo de TLS 1.3: cuando el servidor recibe el mensaje ClientHello, toma una AEAD (cifrada), un algoritmo de firma y una compartición de clave de cliente que admita. Responde con un mensaje ServerHello que contiene la AEAD elegida y la compartición de clave de servidor para el acuerdo de claves seleccionado. Una vez fijadas la AEAD y la clave compartida, el servidor empieza a encriptar los datos (en verde en el diagrama).
Autenticación
Junto con la AEAD y la compartición de clave de servidor, este envía una firma, la firma de protocolo de enlace, en la transcripción de la comunicación hasta el momento, junto con un certificado (cadena) para la clave pública que se utiliza para crear la firma. Esto permite que el cliente se autentique en el servidor: comprueba si confía en la entidad de certificación (p.ej. Let’s Encrypt) que ha certificado la clave pública y si la firma verifica los mensajes enviados y recibidos hasta entonces. Esto no solo autentica el servidor, sino que también protege contra ataques de degradación.
Protección contra la degradación
No podemos actualizar al mismo tiempo todos los clientes y servidores a la criptografía poscuántica. Habrá un periodo de transición donde solo algunos clientes y servidores admitirán la criptografía poscuántica. La negociación del acuerdo de claves en TLS 1.3 lo permite. Durante la transición, los clientes y servidores seguirán admitiendo acuerdos de claves no poscuánticas y, si es necesario, pueden recurrir a ellos.
Esta flexibilidad es fantástica, pero también asusta: si tanto el cliente como el servidor admiten el acuerdo de claves poscuánticas, queremos estar seguros de que también negocian el acuerdo de claves poscuánticas. Esto es así en TLS 1.3, pero no es evidente: las comparticiones de clave, la compartición de clave elegida y la lista de acuerdos de claves admitidos se envían todos ellos en texto sin encriptar. ¿No sería posible que un atacante situado entre ellos eliminara los acuerdos de claves poscuánticas? Esto es lo que llamamos ataque de degradación.
Aquí es donde la transcripción desempeña un papel: la firma del protocolo de enlace toma el control de todos los mensajes recibidos y enviados por el servidor hasta ese momento. Esto incluye los acuerdos de claves admitidos y el acuerdo de claves que se ha seleccionado. Si un atacante cambia la lista de acuerdos de claves admitidos que envía el cliente, el servidor no se dará cuenta. No obstante, el cliente comprueba la firma del protocolo de enlace del servidor respecto a la lista de acuerdos de claves admitidos que ha enviado realmente y así detecta cualquier conducta maliciosa.
Los problemas de los ataques de degradación son mucho más complicados para TLS 1.2, y esta es una de las razones por las que tenemos dudas respecto a readaptar la seguridad postcuántica a TLS 1.2.
Encapsulamiento del protocolo de enlace
La última parte de la respuesta del servidor es "server finished", un código de autenticación de mensajes (MAC) de toda la transcripción hasta el momento. Aunque la firma del protocolo de enlace ha realizado casi todo el trabajo, en otros modos operativos de TLS sin firma de protocolo de enlace, como por ejemplo la reanudación de sesión, esto es importante.
Con la AEAD elegida y la compartición de clave de servidor, el cliente puede calcular la clave compartida y desencriptar y verificar la cadena de certificados y la firma y el MAC del protocolo de enlace. No lo hemos mencionado antes, pero la clave compartida no se utiliza directamente para la encriptación. Se combina con las transcripciones de la comunicación para obtener varias claves específicas que se utilizarán posteriormente durante el protocolo de enlace y la conexión principal.
Para encapsular el protocolo de enlace, el cliente envía su propio MAC del protocolo de enlace y, a continuación, envía los datos cifrados específicos de la aplicación con las claves derivadas durante el protocolo de enlace.
Hello! Retry Request?
Lo que acabamos de describir esquemáticamente es el flujo recomendable, donde el cliente envía una compartición de clave que admite el servidor. Este podría no ser el caso. Si el servidor no acepta los acuerdos de claves que anuncia el cliente, se lo indicará e interrumpirá la conexión.
Si hay un acuerdo de claves que ambos admiten, pero para el que el cliente no ha enviado una compartición de clave, el servidor responderá con un mensaje HelloRetryRequest (HRR), que solicita una compartición de clave de un acuerdo de claves específico que admite el cliente, tal como se muestra en el diagrama de la derecha. A su vez, el cliente responde con un nuevo ClientHello con la compartición de clave seleccionada.
Y esto no es todo: también se permite a un servidor enviar un mensaje HelloRetryRequest para solicitar un acuerdo de claves distinto que prefiera a aquellos para los que el cliente ha enviado comparticiones. Por ejemplo, un servidor puede enviar un mensaje HelloRetryRequest a un acuerdo de claves poscuánticas si el cliente lo admite, pero no ha recibido una compartición de clave para él.
Actualmente, los mensajes HelloRetryRequest no son habituales. Prácticamente todos los servidores que admiten el acuerdo de claves X25519 y prácticamente todos los clientes (actualmente el 98 %) envían una compartición de clave X25519. Anteriormente, P-256 era el estándar. Durante mucho tiempo, muchos navegadores enviaban una compartición de clave P-256 y una compartición de clave X25519 para evitar un mensaje HelloRetryRequest. Como comentamos anteriormente, podríamos no tener el lujo de enviar dos compartitiones de claves poscuánticas.
Esa es la teoría.
TLS 1.3 está diseñado para ser flexible en la criptografía que utiliza sin sacrificar la seguridad o el rendimiento, lo que es adecuado para nuestra migración a la criptografía poscuántica. Esa es la teoría, pero en la práctica surgen algunos problemas importantes. Profundizaremos en ellos más adelante. Primero, echemos un vistazo a los acuerdos de claves poscuánticas que hemos implementado.
Qué hemos implementado
Hoy, hemos activado el soporte de los acuerdos de claves X25519Kyber512Draft00 y X25519Kyber768Draft00 utilizando los identificadores de TLS 0xfe30 y 0xfe31, respectivamente. Son exactamente los mismos acuerdos de claves que activamos en julio en un número limitado de zonas.
Estos dos acuerdos de claves son una combinación, un híbrido, del acuerdo X25519 clásico y de los nuevos acuerdos poscuánticos Kyber512 y Kyber768, respectivamente, y en ese orden. Esto significa que, si resulta que Kyber no es seguro, la conexión mantiene la seguridad de X25519.
Por ahora, Kyber es el único acuerdo de claves que NIST ha seleccionado para la estandarización. Kyber utiliza muy poca CPU: es más rápido que X25519, cuya rapidez ya es conocida. Por otro lado, sus comparticiones de claves son mucho mayores:
Tamaño de las comparticiones de claves (en bytes) | Ops/s (preferibles los valores más altos) | ||||
---|---|---|---|---|---|
Algoritmo | PQ | Cliente | Servidor | Cliente | Servidor |
Kyber512 | ✅ | 800 | 768 | 50 000 | 100 000 |
Kyber768 | ✅ | 1 184 | 1 088 | 31 000 | 70 000 |
X25519 | ❌ | 32 | 32 | 17 000 | 17 000 |
Comparativa de tamaño y rendimiento de CPU entre X25519 y Kyber. El rendimiento varía considerablemente según la plataforma de hardware y las restricciones de implementación, y solo se debe considerar como una indicación aproximada.
Antes de que NIST realice la estandarización final en 2024, se esperan pequeños cambios en Kyber, pero no serán compatibles con las versiones anteriores. Además, el grupo de trabajo de TLS aún no ha concluido la integración con TLS, incluidos la selección y los detalles del acuerdo de claves híbridas. Cuando esto suceda, los adoptaremos rápidamente.
Por ello, queda mucho tiempo hasta que admitamos los acuerdos de claves preliminares anunciados hoy. Se proporcionan como un servicio beta. Publicaremos actualizaciones sobre nuestra implementación en pq.cloudflareresearch.com y lo anunciaremos en la lista de correo de IETF PQC.
Ahora que sabemos cómo funciona la negociación de TLS, en teoría, y qué acuerdos de claves estamos añadiendo, ¿cómo podría no funcionar?
Dónde esto puede fallar en la práctica
Osificación de protocolo
A menudo, los protocolos están diseñados teniendo en cuenta la flexibilidad, pero si esa flexibilidad no se pone en práctica, con frecuencia se pierde. Esto se denomina osificación de protocolo. La implementación de TLS 1.3 era difícil debido a varios casos de osificación. Un ejemplo singular es la negociación de versión de TLS: el mensaje ClientHello contiene un campo de versión que indica la última versión que admite el cliente. Se asignó una nueva versión a TLS 1.3, pero las pruebas evidenciaron que muchos servidores no recurrían a TLS 1.2, sino que causaban un error de conexión. ¿Cómo abordamos la osificación?
Solución
Hoy, TLS 1.3 se muestra como TLS 1.2 hasta el punto de incluir muchos campos heredados en el mensaje ClientHello. La propia negociación de versión se pasa a una nueva extensión del mensaje. Un servidor TLS 1.2 ignorará la nueva extensión y continuará con TLS 1.2, mientras que un servidor TLS 1.3 tomará la extensión y continuará adecuadamente con TLS 1.3.
Engrasado de protocolo
¿Cómo evitamos la osificación? Aprendida esta lección, los navegadores anunciarán periódicamente versiones "ficticias" en este nuevo campo de versión, para detectar de forma temprana los servidores que se comporten incorrectamente. Lo hacen así no solo para el campo de versión nueva, sino en muchos otros lugares del protocolo de enlace TLS, y, premonitoriamente, para los identificadores de acuerdos de claves. Hoy, el 40 % de los navegadores envían dos comparticiones de claves de cliente: una X25519 y una compartición de clave ficticia de 1 byte para mantener la flexibilidad del acuerdo de claves.
Este comportamiento está estandarizado en el mecanismo RFC 8701: Generate Random Extensions And Sustain Extensibility (GREASE) y lo llamamos engrasado de protocolo, como en el "engrasado de juntas" de la metáfora de Adam Langley de que los protocolos tienen juntas oxidadas que requieren aceite.
Este engrasado de la compartición de clave ayuda, pero no es la solución perfecta, porque en este caso lo que causa mayor preocupación es el tamaño de la compartición de clave.
ClientHello fragmentado
Las comparticiones de claves poscuánticas son grandes. Las dos claves híbridas Kyber tienen un tamaño de 832 y 1216 bytes. En comparación, X25519 es diminuta, con solo 32 bytes. No es improbable que algunas implementaciones fallen al ver comparticiones de claves tan grandes.
Nuestra mayor preocupación es acerca de la compartición de clave basada en Kyber768 más grande. Un ClientHello con la compartición de clave basada en Kyber512 de 832 bytes más pequeña apenas cabrá en un paquete TCP típico. Por otro lado, la compartición de clave Kyber768 de 1216 bytes más grande normalmente fragmentará el ClientHello en dos paquetes.
El ensamblado de los paquetes no es gratuito. Requiere que hagas un seguimiento de los mensajes parciales circundantes. Normalmente, esto lo hace de forma transparente la pila TCP del sistema operativo, pero los intermediarios optimizados y los equilibradores de carga que analizan cada paquete individualmente deben hacer un seguimiento de las propias conexiones, y es posible que no lo hagan.
QUIC
La situación para HTTP/3, que se basa en QUIC, es especialmente interesante. En lugar de un número de puerto simple que elige el cliente (como en TCP), un paquete QUIC del cliente contiene un ID de conexión que elige el servidor. Considera que son el equivalente a “tu referencia” y “nuestra referencia” en el correo postal. Esto permite a un equilibrador de carga QUIC codificar la máquina determinada que gestiona la conexión al ID de conexión.
Al abrir una conexión, el cliente QUIC no sabe qué ID de conexión desea el servidor, y envía uno aleatorio. Si el cliente requiere varios paquetes iniciales, como por ejemplo un ClientHello grande, utilizará el mismo ID de conexión aleatorio. Aunque el estándar QUIC permite varios paquetes iniciales, es posible que un equilibrador de carga QUIC no espere esto, y no podrá hacer referencia a la conexión TCP subyacente.
Rendimiento
Aparte de estos fallos graves, los fallos leves, como por ejemplo la degradación del rendimiento, también son preocupantes: si la carga de un sitio web es demasiado lenta, es posible que este esté dañado desde el principio.
En 2019, en un experimento conjunto con Google, implementamos dos acuerdos de claves poscuánticas: CECPQ2, basado en NTRU-HRSS, y CECPQ2b, basado en SIKE. NTRU-HRSS es muy similar a Kyber: es un poco más grande y lento. Los resultados de 2019 son muy prometedores: cuesta distinguir X25519+NTRU-HRSS (línea naranja) de X25519 por sí solo (línea azul).
Seguiremos vigilando de cerca el rendimiento, especialmente el rendimiento de cola: queremos una transición fluida para todos, del cliente más rápido al más lento en Internet.
Cómo ayudar
Internet es un sistema muy heterogéneo. Para encontrar todos los problemas, necesitamos un número suficiente de distintos verificadores. Trabajamos con navegadores para añadir soporte para estos acuerdos de claves, pero es posible que no haya uno de estos navegadores en cada red.
Por lo tanto, para ayudar a Internet, prueba y pasa una pequeña parte de tu tráfico a los dominios de Cloudflare para utilizar estos nuevos métodos de acuerdos de claves. Tenemos bifurcaciones de código abierto para BoringSSL, Go y quic-go. Para BoringSSL y Go, consulta el código de muestra aquí. Si tienes alguna duda, contacta con nosotros en la dirección [email protected]. Comentaremos los problemas y soluciones en el grupo de trabajo de TLS de IETF.
Perspectiva
La transición a una red de Internet poscuántica segura es urgente, pero no está exenta de desafíos. Hoy, hemos implementado un acuerdo de claves poscuánticas preliminar en todos nuestros servidores (una parte considerable de Internet) por lo que ya podemos empezar a probar la gran migración. Esperamos que, en 2024, cuando NIST dé el toque final a Kyber, todos hayamos sentado las bases para una transición fluida a una red de Internet poscuántica.
.....
1Solo admitimos estos acuerdos de claves poscuánticas en protocolos basados en TLS 1.3, incluido HTTP/3. No hay excepciones: por el momento inhabilitamos estos intercambios de claves híbridas para los sitios web en modo FIPS.