Muchos de los sitios que visitamos diariamente están protegidos por HTTPS. Gmail, Twitter, Facebook o Google son sólo unos ejemplos. Nos dicen que es por nuestra seguridad pero, ¿cómo nos protege ese protocolo? ¿Qué ventajas tiene frente a HTTP normal? Y, lo más importante: ¿Cómo funciona?
Vamos a intentar dar respuesta a todas esas preguntas en este artículo, empezando por la más importante: ¿por qué necesitamos HTTPS?
Imagino que todos sabréis qué es HTTP, el protocolo que utilizan los navegadores para comunicarse con los servidores web y que te permite ver páginas web como esta. Funciona bien pero tiene un problema: la seguridad.
Con HTTP, cualquier dato se transmite en texto plano, sin cifrar. Es decir, que cualquiera que se conecte a tu red WiFi, o que tenga acceso a la comunicación entre tu ordenador y el servidor (tu ISP, por ejemplo) puede ver todos los datos que recibes y envías. Por ejemplo, podrían ver las contraseñas que usas para entrar en tu correo, o realizar operaciones adicionales cuando navegas por la web de tu banco.
¿Qué es HTTPS?
Hay que cifrar esos datos para evitar que nadie más pueda verlos. Para eso está el protocolo HTTPS (Hyper Text Transfer Protocol Secure). En sí mismo HTTPS no es más que HTTP normal sobre SSL/TLS.
SSL/TLS (Secure Sockets Layer/Transmission Layer Security) son dos protocolos para enviar paquetes cifrados a través de Internet, siendo el último el más moderno. Sirven igual para HTTP que para cualquier otro protocolo de comunicación, aunque en este artículo veremos únicamente su aplicación en HTTPS.
¿Cómo se establece una conexión segura?
Como bien sabéis, para cifrar datos se necesita una clave. Esa clave tendrá que saberla tanto el navegador como el servidor para poder comunicarse. El primer problema aparece rápidamente: ¿cómo compartimos una clave de forma segura (sin que nadie más pueda saberla)? Está claro que la clave tiene que ser única para cada conexión, por lo que no puede venir preconfigurada en los ordenadores.
Aquí entra en juego una de las maravillas de la criptografía moderna: un sistema de clave pública/clave privada, cifrado asimétrico que ya nos explicaron en Genbeta Dev.
La pre-clave se genera en el navegador, y se comparte con el servidor usando criptografía asimétrica
Las claves pública y privada son un par de números relacionados de una forma especial, de tal forma que un mensaje cifrado con una clave sólo puede ser cifrado con su par correspondiente. Por ejemplo, si quiero enviar un mensaje a un servidor, lo cifro con su clave pública para que sólo se pueda descifrar con su clave privada.
Y precisamente este es el primer paso esencial de una conexión HTTPS. Después de haber acordado detalles técnicos entre navegador y servidor (versión del protocolo, algoritmos de cifrado asimétrico y simétrico que se usarán…), el navegador cifra una preclave generada en el momento con la clave pública del servidor al que nos queremos conectar. Eso se envía al servidor, que descifra la preclave con su clave privada.
Tanto el servidor como el navegador aplicarán un cierto algoritmo a la preclave y obtendrán la misma clave de cifrado. De esta forma hemos superado el primer (y mayor) problema que teníamos: intercambiar la clave. A partir de entonces, simplemente se cifran y descifran los datos con esa clave.
Como nadie más sabe esa clave, nuestras comunicaciones serán seguras y nadie podrá verlas (siempre y cuando el algoritmo de cifrado simétrico sea seguro, claro).
Alguno se preguntará por qué intercambiar una clave y no cifrar directamente los datos usando cifrado asimétrico. La principal razón es que el cifrado simétrico es muchísimo más rápido que el asimétrico, e intercambiar la clave no resulta un problema que haya que sortear.
¿Qué datos protege HTTPS?
La pregunta obvia es saber qué datos se protegen cuando usamos una conexión HTTPS. Como está basado en SSL/TLS, que funciona en la capa más baja de comunicación, se cifran todos los datos de HTTP. Esto es, no sólo la página web sino también la URL completa, los parámetros enviados, las cookies… Lo único que se queda al descubierto son los datos del paquete TCP: el servidor y el puerto al que nos conectamos.
HTTPS sólo deja al descubierto el servidor y puerto al que nos conectamos.
Por lo tanto, HTTPS no sólo impide que alguien vea las páginas web que estamos visitando. También impide que puedan conocer las URLs por las que nos movemos, los parámetros que enviamos al servidor (por ejemplo, los usuarios y contraseñas se envían como parámetros POST normalmente) o las cookies que enviamos y recibimos (alguien con acceso a estas cookies podría robar nuestra sesión, como demostraba la herramienta Firesheep).
¿Cómo sé qué no me estoy comunicado con un impostor?
![Certificado SSL](https://i0.wp.com/i.blogs.es/861ffe/sslcert/450_1000.png?w=1200&ssl=1)
Hay un problema adicional en la comunicación por Internet. Pongamos que quiero navegar a Genbeta.com. ¿Cómo sé que me estoy comunicando con el servidor de Genbeta y no con un servidor falso que se está haciendo pasar por Genbeta (lo que se conoce como un ataque man-in-the-middle)?
Por lo tanto, hay que autenticar los servidores. No sirve de nada tener los datos cifrados si no nos aseguramos de que nos estamos conectando al servidor correcto. Para eso están los certificados SSL, que contienen la clave pública y los nombres de dominio en los que se pueden usar.
Las CA (terceros de confianza) nos aseguran que el certificado es válido y que el servidor es quien dice ser.
El certificado SSL por sí sólo no sirve para nada. Cualquier atacante podría falsear uno y no te darías cuenta. Ahí entran en juego las CA, o Certificate Authority, las entidades emisoras de certificados SSL firmados, que sólo dan certificados sobre un dominio a su propietario. No podría, por ejemplo, ir cualquiera y pedir un dominio para google.com. Además, las firmas aseguran que el contenido del certificado no ha variado. No voy a extenderme viendo cómo es este proceso, ya lo vimos en un artículo anterior.
En resumen, una firma de una CA nos asegura que el servidor es quien dice ser. Por supuesto, hay que verificar esa firma para asegurarse de que es real. Para ello, el navegador busca el certificado en su almacén (en realidad es una anillo de confianza, algo más complejo) y verifica la firma. Si no es válida o no encuentra el certificado, te mostrará un aviso de que no puede autenticar la conexión al servidor.
Precisamente esto último ocurría hace un tiempo con Firefox (y otros navegadores, creo), cuando intentabas conectarte a servidores seguros de la administración española. Los certificados de esos servidores estaban firmados por la FNMT, pero Firefox no tenía en su almacén los certificados de la FNMT. Por esto mismo no podía asegurar que el certificado fuese válido y avisaba al usuario.
¿Qué debilidades tiene HTTPS?
El punto más débil de HTTPS son los certificados. Si, por ejemplo, alguien roba el certificado (con la clave privada) de Google, podría crear un servidor falso sin que hubiese forma de distinguirlo de uno legítimo.
Un problema más grande puede ocurrir si se filtra la clave privada de una CA. Un atacante podría crear y firmar certificados válidos para cualquier dominio sin que nadie se lo impidiese, y por lo tanto engañar a los usuarios para que se conectasen a servidores falsos.
Por suerte, todos los navegadores tienen un mecanismo para revocar certificados. Cuando se compromete un certificado, se pone su huella digital del certificado en una lista. El navegador se descarga esa lista y dejará de dar por válido cualquier certificado que aparezca ahí. El único problema está en que los navegadores no siempre aprovechan bien esas listas, pero el mecanismo está ahí.
Con esto, ya hemos acabado nuestra entrega de la serie “Así funciona…” sobre HTTPS. Podréis imaginar, especialmente los más legos en la materia, que hay cosas que he pasado por alto y otras que se han simplificado para hacer más fácil la lectura. Como siempre, intentaremos resolver las dudas y críticas que tengáis en los comentarios.