Introducción a la seguridad en la web
En este artículo haremos una breve introducción de algunos conceptos de seguridad en la web. Concretamente nos centraremos en el uso de la comunicación cifrada en las aplicaciones web, el uso del protocolo HTTPS, los certificados y las autoridades certificadoras.
Debilidades de la comunicación a través de internet
Desde el principio de los tiempos de la comunicación, entre seres humanos, ha existido la necesidad de mantener comunicaciones secretas. Por razones más o menos legítimas, es habitual la necesidad de comunicar algo a alguien sin que los demás se enteren.
En las comunicaciones personales, la mejor manera de conservar el secreto de es, de hecho, mantener en secreto el acto de la comunicación en sí. Comentar algo "en privado" garantiza que nuestro mensaje se mantendrá oculto ya que nadie sabe, ni siquiera, que se ha producido una comunicación. Si no podemos asegurar una comunicación velada si que podemos, al menos, ocultar el mensaje de manera que no sea interceptable. Como, por ejemplo, cuando decimos algo a alguien "en voz baja". Es decir, los demás saben que existe una comunicación pero no pueden escucharla, saben que ha habido mensaje, pero no saben cual es.
Sin embargo esta idea, a distancia, la seguridad es más compleja. Para mantener la seguridad en dichas comunicaciones deberíamos asegurarnos de que se cumplen una serie de puntos:
- El receptor es quien dice ser y no un impostor: al mantener esa comunicación a distancia no podemos simplemente "ver" que estamos hablando con quien queríamos hablar y que efectivamente es quien dice ser. Necesitamos un mecanismo que nos garantice que quien recibe el mensaje es aquel a quien queremos enviárselo.
- El mensaje no debe ser interceptado por un tercero: incluso sabiendo que le estamos enviando el mensaje a la persona correcta, deberíamos asegurarnos de que no hay un tercero que también recoja ese mensaje.
- El mensaje que llega es el que enviamos: podría pasar que alguien haga llegar otro mensaje al receptor, mensaje que el receptor pensará que es nuestro.
Webs no seguras
En primer lugar hablaremos de las webs que no son seguras. Son aquellas webs en las que no existe la necesidad de mantener en secreto ninguna comunicación. Sea porque el mensaje es de poca importancia o porque es público. Por ejemplo; cuando alguien entra en un diario a leer una noticia, el lector no envía ninguna información al diario, con lo cual no hay mensaje que mantener en secreto, y la noticia en sí es pública, el diario no tiene necesidad de mantener la noticia en secreto, no tiene sentido en este caso. Una web de publicidad de una empresa también cumple esta característica, no hay ninguna necesidad de mantener oculto aquello que la empresa quiere hacer público a través de la web, precisamente lo que necesita es que el mensaje sea legible y llegue a cuantas más personas mejor.
Estas webs que no tienen ninguna necesidad de seguridad en las comunicaciones trabajan sobre el canal HTTP (Hypertext Transfer Protocol). Así, nuestro navegador sabe que no debe preocuparse por la comunicación con esa web.
Webs seguras
Sin embargo otras webs si que necesitan ser seguras. Un ejemplo es la comunicación con nuestro banco. Hoy día cualquier entidad bancaria ofrece a sus clientes la posibilidad de controlar su cuenta telemáticamente a través de la web. El banco nos provee de un usuario y una contraseña de manera que nadie tenga acceso a nuestra cuenta si no conoce nuestra contraseña, perfecto, debemos ser celosos a la hora de mantener nuestra contraseña en secreto. Pero ¿es eso suficiente?.
Tal y como hemos apuntado en la introducción no podemos estar seguros de que nadie escucha e intercepta nuestros mensajes, entonces, por mucho cuidado que pongamos a la hora de mantener nuestra contraseña en secreto, ¿quién nos garantiza que nadie la ve cuando se la enviamos al banco?, ¡no podemos no enviársela!
También deberíamos estar seguros que cuando hablamos con el banco hablamos realmente con él y no con un impostor. Una de las técnicas mas conocidas de hacking es el conocido como phishing que se describe en la Wikipedia como: término informático que denomina un modelo de abuso informático y que se comete mediante el uso de un tipo de ingeniería social caracterizado por intentar adquirir información confidencial de forma fraudulenta (como puede ser una contraseña o información detallada sobre tarjetas de crédito u otra información bancaria). El cibercriminal, conocido como phisher, se hace pasar por una persona o empresa de confianza en una aparente comunicación oficial electrónica, por lo común un correo electrónico, o algún sistema de mensajería instantánea o incluso utilizando también llamadas telefónicas. Es decir, alguien se hace pasar por el banco, tu crees que estás hablando con él, cuando envías tus datos de acceso (el usuario y la contraseña) se las estás dando a un delincuente que tendrá control total de tus cuentas.
¿Cómo podemos protegernos ante tanta posibilidad de que nos roben la identidad? La solución pasa por el cifrado de mensajes.
Comunicaciones cifradas
Cifrar un mensaje, según la Wikipedia es: utilizar un algoritmo de cifrado con cierta clave (clave de cifrado) que transforma un mensaje, sin atender a su estructura lingüística o significado, de tal forma que sea incomprensible o, al menos, difícil de comprender a toda persona que no tenga la clave secreta (clave de descifrado) del algoritmo. Es decir, entregar un mensaje ilegible sabiendo que nuestro receptor legítimo - y solo él - conoce la manera de recuperar el mensaje legible original. En realidad la manera es aplicar una clave que mediante una transformación matemática encripta (hace ilegible) o desencripta (hace legible) el mensaje. Por tanto la manera de transformar el mensaje es conocida por todos, pero al ser necesaria la clave sólo podrá descifrarse por aquellas personas que la conozca.
Estas comunicaciones cifradas se realizan mediante el canal HTTPS (Hypertext Transfer Protocol Secure). Nuestro navegador sabe que cuando una web se comunica por éste canal debe aplicar los mecanismos de seguridad pertinentes.
Claves simétricas
Como se apunta en el párrafo anterior la encriptación va ligada íntimamente al uso de claves. Si la encriptación y desencriptación se realiza mediante la misma clave, estamos hablando de claves simétricas. En este caso el cifrado funcionaría como un candado o una cerradura normal y corriente. Un candado se cierra con una llave y es con la misma llave que se abre. Sólo es necesaria una llave. Podemos tener dos llaves, pero ambas llaves serán iguales, da igual cual de las dos usemos para abrir o cerrar.
El funcionamiento es exactamente el mismo que con el caso del candado. Enviamos un paquete (mensaje) cerrado (cifrado) con un candado a un amigo, el receptor tiene la misma llave que nosotros (o bien se la hemos hecho llegar por otro lado o bien habían dos copias de la misma llave) y cuando le llega el paquete (mensaje) lo abre (descifra) con dicha llave y puede ver el contenido. Nadie más ha podido abrir el paquete, nadie más ha podido ver el contenido. Es una manera de cifrar perfectamente válida y segura (siempre que tengamos mucho cuidado al guardar las llaves).
Sin embargo esta forma de cifrar tiene desventajas y la más evidente es la cantidad de llaves que tenemos que cuidar. Supongamos que queremos enviar nuestros paquetes cerrados, pero que en vez de un amigo tenemos unos miles (un banco tiene miles de clientes). Necesito una llave por cada amigo o el sistema se volverá inseguro, si yo sólo usase una llave para cerrar todos los paquetes y todos mis amigos tuvieran copia de esa llave ¡ocurriría que uno de mis amigos puede abrir el paquete de otro! Entre amigos puede no parecer grave, pero entre clientes de banco la cosa cambia. A nadie le gustaría que otros clientes del mismo banco tuvieran la llave de nuestras cuentas.
Intentando ponerlo en un lenguaje pseudomatemático podemos decir que si m es el mensaje que queremos cifrar, cifrarlo es aplicarle una clave F, que podemos escribir como F(m) que lo hace ilegible. Así, m es legible, pero F(m) es ilegible, nadie que capture la comunicación (al menos en el mundo civil) podrá deducir m a partir de F(m). Cuando decimos que se usa la misma clave para cifrar y descifrar nos referimos a que: F(F(m)) == m (aplicar la clave a un mensaje al que ya le habíamos aplicado la clave retorna el mensaje original)
Claves asimétricas
Continuando con el ejemplo del candado imaginemos un candado más complejo, necesita dos llaves, y se comporta de la siguiente manera: si cerramos el candado con la primera llave, el candado sólo se abrirá si usamos la segunda llave, y viceversa, es decir, si cerramos el candado con la segunda llave entonces el candado sólo se puede abrir utilizando la primera llave.
En lenguaje pseudomatemático podemos decir que teniendo el mensaje m y las claves F y G, diremos que m es legible, que F(m) es ilegible y G(m) también es ilegible. Además diríamos que G(F(m)) == m (aplicar la clave G al mensaje cifrado F(m) retorna el mensaje original) y que F(G(m)) == m (aplicar la clave F al mensaje cifrado G(m) retorna el mensaje original). Con este tipo de claves no podemos usar solo una, es decir F(F(m)) != m y G(G(m)) != m al contrario que las claves simétricas. Es este tipo de claves el que utilizamos para cifrar las comunicaciones vía web.
Esto podría parecer un poco contradictorio, ¿qué ventaja nos otorga el hecho de que necesitemos dos llaves en vez de una? al final y al cabo nuestro problema era guardar llaves y ahora manejamos el doble. Veremos que aplicando un poco de ingenio, y haciendo alguna concesión en cuanto a seguridad, podemos manejar solo dos llaves y sin embargo mantener comunicaciones seguras con todos nuestros amigos.
Claves públicas y privadas
Vamos a ver como es posible que el banco me asegure la comunicación con ellos manteniendo sólo un par de claves. Para esto es necesario entender que este par de claves (cuando hablamos de una clave asimétrica en realidad hablamos de un par de claves, un candado que necesita un par de llaves) tiene la siguiente característica: una de las claves es pública (la conoce todo el mundo) y la otra clave es privada (solo la conoce el banco).
Para nuestras fórmulas en lenguaje pseudomatemático diremos que el mensaje es m que la clave pública es P y que la clave privada es p. Recordemos del punto anterior que entonces P(m) es ilegible, que p(m) también es ilegible, que P(p(m)) == m (aplicar la clave pública a un mensaje al que ya se le había aplicado la clave privada retorna el mensaje original) y que p(P(m)) == m (aplicar la clave privada a un mensaje al que ya se le había aplicado la clave pública retorna el mensaje original).
Certificados
Como hemos dicho el banco tiene una calve pública P. Esa clave la conoce todo el mundo y es lo que se denomina certificado.
Cuando nos conectamos por primera vez a una web segura nuestro navegador recibe un certificado y nos pregunta si confiamos en que la web a la que nos conectamos es realmente a la que nos queríamos conectar y, si es así, guardará el certificado para futuras conexiones. A partir de ese momento siempre que nos queramos comunicar con esa web nuestro navegador usara ese certificado como clave para cifrar o descifrar las comunicaciones, si cambiamos de navegador, hay que volver a empezar el proceso.
A partir de ese momento el banco nos enviará mensajes del tipo p(m) (aplicará su clave privada a los mensajes) y como nosotros conocemos la clave pública P (la tenemos guardada mediante el certificado correspondiente)
podremos aplicarla a lo que nos envíen y tendremos P(p(m)) que como hemos visto en párrafos anteriores es igual a m, es decir, podemos leer el mensaje. Es muy importante entender lo que esto implica: todo el mundo dispone de la clave pública del banco, cualquier persona puede ver que es lo que el banco nos envía.
Hay cierto mito que dice que las webs que van por HTTPS están encriptadas y no es verdad. Cualquiera puede leer los mensajes que nos envía el banco, cualquiera, todo el mundo. Por eso el banco nunca envía información realmente crítica a través de la web. Nunca verás escrita en pantalla las contraseñas, los números PIN, las claves de seguridad de la tarjeta de crédito... nada. Y sí, cualquier hacker que intercepte nuestra comunicación puede saber cuanto dinero tenemos en la cuenta o cuales son nuestros movimientos. Estas son las concesiones a la seguridad que se han comentado antes.
Entonces ¿de qué sirve todo esto?. De momento ya sabemos que lo que nos envía el banco no es privado, ¿dónde está la seguridad que buscamos?. Pues bien, este mecanismo nos garantiza tres cosas:
- El mensaje viene de la persona que posee el certificado (en este caso el banco): si el mensaje se puede descifrar con la clave pública del banco, necesariamente se ha cifrado con la clave privada del banco. Si se hubiera cifrado con cualquier otra clave, la que tenemos nosotros no serviría para descifrarlo. Por tanto ya tenemos la garantía de que hablamos con la misma organización que nos dio el certificado. Dado que la clave del banco es privada y nadie más la tiene, nadie que no sea el banco puede haber cifrado ese mensaje.
- El mensaje no ha sido modificado: esto no es tan evidente y de hecho se utiliza una técnica llamada firma mediante la cual podemos garantizar la integridad del mensaje. El banco genera su mensaje (aquello que veremos en el navegador) y genera un hash sobre ese mensaje, por ejemplo un MD5 (una función de hash retorna valores muy distantes con entradas muy parecidas, o lo que es lo mismo, el más mínimo cambio en el mensaje original hace que el resultado del hash sea muy diferente) y después cifra ese MD5. A nosotros nos envía el mensaje m y el MD5 cifrado o firma p(MD5(m)). Nuestro navegador recibe el mensaje y calcula su MD5 MD5(m), por otro lado descifra el MD5 que ha recibido del banco mediante la clave pública del banco P(p(MD5(m))) que como ya sabemos es MD5(m), acto seguido compara ambos resultados. Si el MD5 calculado por nosotros es igual al MD5 descifrado mediante el certificado es que el mensaje es exactamente aquel que se nos envió originalmente. Nadie puede firmar en nombre del banco, ya que para eso debería conocer su clave privada.
- Nuestras comunicaciones hacia el banco si que están encriptadas: efectivamente cuando nosotros enviamos un mensaje al banco, en realidad le enviamos P(m). Como hemos visto en párrafos anteriores los mensajes cifrados con una clave sólo se pueden descifrar con la otra (el hecho de tener la llave con la que se cerró el candado no nos permite abrirlo) con lo que, aunque miles de personas conozcan la clave pública sólo el banco, mediante la clave privada, puede descifrar nuestro mensaje. He ahí la magia que permite que todos nos comuniquemos con el banco de manera segura, pese a que todos tenemos una de las llaves para abrir los mensajes, y el banco solo ha de tener una llave para abrir los mensajes de todos. Con un único par de claves miles de personas se comunican de manera segura.
Entidades certificadoras
Este mecanismo que hemos descrito anteriormente tiene una debilidad evidente. Hay un paso al principio que podrían explotar los delincuentes para engañarnos. Supongamos que por alguna treta hacker como DNS poisoning (por la cual se engaña a un ordenador para que cuando se conecte a una dirección web vaya a una IP controlada por el hacker) nosotros la primera vez que nos conectamos a nuestro banco recibimos el certificado y le decimos que confiamos en que es quien dice ser (la URL es la de nuestro banco y el hacker se ha asegurado que la apariencia de su web sea exactamente igual que la de nuestro banco) y el navegador se guarda la clave del hacker. A partir de ahí viviremos engañados, nosotros creeremos que estamos manteniendo una comunicación segura, por un canal seguro, con nuestro banco y en realidad nos estaremos comunicando con un impostor... ¿Cómo se soluciona eso?.
En realidad cuando nos comunicamos con un banco no utilizamos el mecanismo descrito anteriormente. En realidad el banco nos envía un certificado seguro. Un certificado con garantías de que realmente es ese y no otro es el certificado del banco. ¿Cómo lo hace? a través de una autoridad certificadora.
Las entidades certificadoras son grandes empresas de cuya legalidad nos tenemos que fiar (ellos pagan mucho dinero para que estados, bancos y demás organizaciones confíen en que realmente son legales. Hay que fiarse. Es como cuando ponemos una alarma en casa, nos tenemos que fiar que aquel que instala la alarma es legal). Estas entidades son tan fiables que nuestro navegador lleva incorporados sus certificados (sus claves públicas). No es necesario instalarlas la primera vez que visitamos ninguna web, no nos pueden engañar porque nuestro navegador sabe de antemano cual es el certificado. Esto puede comprobarlo el lector si va a los certificados de su navegador (menú configuarción > seguridad > certificados) y observa el apartado "Entidades de certificación raíz de confianza" (esto puede cambiar según el navegador). ahí tendrá una serie de certificados que él no instaló y que pertenecen a entidades certificadoras.
Mediante estos certificados el banco puede garantizarnos que es quien dice ser incluso la primera vez que nos conectamos. Recordemos que el banco nos envía un certificado o clave pública que hemos llamado P. Pues bien, en realidad el banco nos envía un certificado que a su vez está encriptado con la clave privada de una entidad certificadora.
En lenguaje pseudomatemático supongamos que existen el par de claves G/g (la G es de Go Daddy, entidad certificadora) y que, siguiendo la nomenclatura anterior, G es la clave pública de Go Daddy y g es la clave privada de Go Daddy; en ese caso el banco no envía P sino que envía g(P) aplica la clave privada de Go Daddy a su certificado). ¿Como puede enviar un banco algo encriptado con la clave privada de Go Daddy, si esa clave sólo la posee Go Daddy?, muy sencillo, el banco compra el certificado. El banco va con su certificado a Go Daddy y le paga para que estos le den el resultado de encriptarlo con su clave privada (nunca le dan la clave, claro, si el banco necesita otro certificado tendrá que pasar de nuevo por caja).
Una vez el banco ha pagado a la entidad certificadora el banco ya tiene un certificado seguro. Cuando nos conectamos por primera vez, el banco nos envía g(P). como nuestro navegador ya tiene la clave pública de Go Daddy G puede aplicarla y así tener G(g(P)). Como ya sabemos aplicar la clave pública tras aplicar la privada retorna el mensaje original, es decir P con lo que nuestro navegador ya sabe P, ya tiene la clave pública del banco, y como ha necesitado usar la clave pública de Go Daddy, tenemos la garantía de que ese mensaje lo ha encriptado Go Daddy, y como nos fiamos de que Go Daddy no dará claves a personas que no acrediten ser quien son (ya hemos comentado que hay que hacer un ejercicio de confianza respecto a las entidades certificadoras) nuestro navegador confía plenamente en que estamos manteniendo una comunicación segura con quien ha pagado por tener un certificado seguro.
Webs muy seguras
¿Entonces no es posible mantener una comunicación completamente privada?. Ya sabemos como mantener una comunicación en que los mensajes que enviamos al banco sean seguros (aunque los que nos envía el banco no lo son), ¿Cómo podemos mantener una comunicación encriptada en ambos sentidos?. La solución que se aplica actualmente es un doble juego de certificados. Un ejemplo es la hacienda pública (en España, al menos). Para poder realizar operaciones con hacienda el ciudadano necesita tener un certificado que le tiene que pedir a hacienda. Con ese certificado el ciudadano cifra sus mensajes con su clave privada (es responsabilidad del ciudadano guardar celosamente la clave que hacienda le da) y el estado posee la clave pública de ese ciudadano concreto. Así hacienda puede descifrar nuestros mensajes. Eso implica que hacienda si tiene que cuidar tantas claves como ciudadanos tengan acceso por internet a sus operaciones, cosa que el banco no hacia por ahorrar y por evitar molestias al cliente. Por eso la comunicación con hacienda es mucho más segura que la comunicación con nuestro banc