A medida que el mundo se orienta cada vez más hacia los datos, el manejo seguro de los datos de los usuarios es más crítico que nunca.
Como desarrolladores, nuestros trabajos ya son lo suficientemente duros: tratar con sistemas altamente complejos y frágiles con múltiples puntos de fallo mientras traducimos deseos humanos revoloteantes en interfaces de usuario y backends. A esta tarea se añade una consideración emergente y esencial: la seguridad de los datos. Y por una buena razón: a nosotros, como clientes, nos enfurece que se haga un mal uso de nuestros datos (así que es justo que demos a nuestros usuarios una experiencia segura y agradable), y los gobiernos y las empresas lo exigen para cumplir la normativa.
La seguridad de los datos como «pasar la pelota
Lo que hace que la seguridad sea más difícil es que tiene varias capas y se convierte en algo así como «la responsabilidad de todos es la responsabilidad de nadie». En un equipo moderno en la nube, varios equipos controlan directamente la entrada/salida de los datos: desarrolladores, administradores de bases de datos, administradores de sistemas (gente de DevOps, si se quiere), usuarios privilegiados de back-office, etcétera. Estos roles/equipos pueden cerrar rápidamente los ojos y pensar que la seguridad de los datos es un problema de los demás. Sin embargo, la realidad es que tienen sus propios mundos de los que ocuparse, ya que un administrador de bases de datos no puede controlar el lado de la aplicación de la seguridad, una persona de DevOps no puede hacer absolutamente nada sobre el acceso al back office, etc.
Los desarrolladores y la seguridad de los datos
Dicho todo esto, los desarrolladores tienen la mayor superficie de acceso cuando se trata de datos: construyen cada parte de la aplicación; se conectan a varios servicios backend; los tokens de acceso de ferry de ida y vuelta; tienen todo el clúster de base de datos para leer/escribir a sus órdenes; las aplicaciones que escriben tienen acceso incuestionable a todas las partes del sistema (por ejemplo, una aplicación Django en producción tiene todos los privilegios para volcar o borrar toda la colección S3 de los últimos diez años), etc. Como resultado, la mayor posibilidad de descuido o negligencia en términos de seguridad existe a nivel del código fuente y es responsabilidad directa del desarrollador.
Ahora bien, la seguridad de los datos es una madriguera de conejo sin fondo, y no hay forma de que pueda siquiera arañar la superficie en un solo post. Sin embargo, quiero cubrir la terminología esencial que los desarrolladores deben conocer para mantener sus aplicaciones seguras. Piense en ello como App Data Security 101.
Empecemos
Hashing
Si desea una definición muy rigurosa, siempre está Wikipedia, pero en términos sencillos, el hashing es el proceso de convertir datos a otra forma, en la que la información es ilegible. Por ejemplo, utilizando el conocido (y muy inseguro) proceso de codificación Base64, la cadena «¿Está mi secreto a salvo contigo?» puede convertirse («hashing») en «SXMgbXkgc2VjcmV0IHNhZmUgd2l0aCB5b3U/». Si empieza a escribir su diario personal en formato Base64, por ejemplo, ¡no hay forma de que su familia pueda leer sus secretos (a menos que sepan descodificar de Base64)!
Esta idea de codificar los datos se utiliza cuando se almacenan contraseñas, números de tarjetas de crédito, etc., en aplicaciones web (en realidad, debería utilizarse en todo tipo de aplicaciones). La idea, por supuesto, es que en caso de violación de los datos, el atacante no pueda utilizar las contraseñas, números de tarjetas de crédito, etc., para hacer daño real. Para realizar este hashing se utilizan algoritmos muy robustos y sofisticados; algo como Base64 será una broma y será descifrado al instante por cualquier atacante.
El hashing de contraseñas utiliza una técnica criptográfica conocida como hashing unidireccional, lo que significa que aunque es posible codificar los datos, no es posible descifrarlos. Entonces, ¿cómo sabe la aplicación que es su contraseña cuando se conecta? Bueno, utiliza el mismo proceso y compara la forma codificada de lo que acaba de introducir como contraseña con la forma codificada almacenada en la base de datos; si coinciden, ¡se le permite iniciar la sesión!
Ya que estamos hablando de hashes, he aquí algo interesante. Si alguna vez ha descargado software o archivos de Internet, es posible que le hayan dicho que verifique los archivos antes de utilizarlos. Por ejemplo, si quiere descargar la ISO de Ubuntu Linux, la página de descarga le mostrará una opción para verificar su descarga; si hace clic en ella, se abrirá una ventana emergente:
La ventana emergente le indica que ejecute un comando, que esencialmente va a hacer un hash de todo el archivo que acaba de descargar y comparará el resultado con la cadena hash que ve en la página de descarga: 5fdebc435ded46ae99136ca875afc6f05bde217be7dd018e1841924f71db46b5
. Esta conversión se realiza utilizando el algoritmo SHA256, cuya mención puede ver en las partes finales del comando: shasum -a 256 --check
.
La idea es que si el hash producido a través de su comprobación es diferente, esto significa que alguien se ha entrometido en su descarga y le ha suministrado un archivo comprometido en su lugar.
Algunos nombres familiares que oirá en el ámbito del hash de contraseñas son MD5 (inseguro y ya desaparecido), SHA-1 y SHA-2 (familias de algoritmos, de las que SHA-256 es miembro, al igual que SHA-512), SCRYPT, BCRYPT, etc.
Salado
Todo tipo de seguridad es un juego del gato y el ratón: el ladrón aprende el sistema actual e inventa una grieta novedosa, que se hace notar, y los fabricantes de cerraduras mejoran su juego, y así sucesivamente. La criptografía no es una excepción. Aunque volver a convertir los hash en contraseñas se ha vuelto imposible, los atacantes han desarrollado con el tiempo técnicas sofisticadas que combinan conjeturas inteligentes con pura potencia de cálculo; como resultado, nueve de cada diez veces pueden predecir la contraseña correcta, dado sólo el hash.
Como resultado, se ha desarrollado la técnica del salting. Lo único que significa es que el cálculo del hash de una contraseña (o de cualquier dato) se hará basándose en una combinación de dos cosas: los propios datos, así como una nueva cadena aleatoria que el atacante no pueda adivinar. Así, con el salting, si queremos hacer un hash de la contraseña superman009
, primero seleccionaríamos una cadena aleatoria como «sal», digamos, bCQC6Z2LlbAsqj77y
luego realizaríamos el cálculo hash sobre superman009-bCQC6Z2LlbAsqj77
. El hash resultante se desviará de las estructuras habituales producidas por el algoritmo, reduciendo enormemente el margen para la ingeniería inversa inteligente o las conjeturas.
Tanto el hashing como el salting son dominios increíblemente complicados y en constante evolución. Así que, como desarrollador de aplicaciones, nunca nos enfrentaríamos directamente a ellos. Pero nos ayudaría mucho conocerlos y poder tomar mejores decisiones. Por ejemplo, si mantiene un framework PHP antiguo y ve por casualidad que utiliza hashes MD5 para las contraseñas, sabrá que ha llegado el momento de introducir otra biblioteca de contraseñas en el proceso de creación de cuentas de usuario.
Claves
Se encontrará a menudo con el término «claves» en el contexto de la encriptación. Hasta ahora, hemos estado cubriendo el hashing de contraseñas o la encriptación unidireccional, donde convertimos los datos de forma irreversible y destruimos la forma original. Esta es una mala idea para el uso práctico diario — ¡un documento escrito y enviado por correo electrónico de forma tan segura que nunca pueda ser leído no sirve de nada! Por lo tanto, queremos cifrar los datos de forma que la información esté abierta para el remitente y el destinatario, pero mientras se transfiere o mientras se almacena, debe ser ilegible.
Para ello, en criptografía existe el concepto de «clave». Es exactamente lo que parece: la llave de una cerradura. La persona que posee la información la codifica utilizando un secreto llamado clave. A menos que el receptor/atacante tenga esta clave, es imposible descifrar los datos, por muy sofisticados que sean sus algoritmos.
Claves rotativas
Aunque las claves hacen que el cifrado sea posible y fiable, conllevan los mismos riesgos que las contraseñas: una vez que alguien conoce la clave, se acabó el juego. Imagine un escenario en el que alguien hackea alguna parte de un servicio como GitHub (aunque sea durante unos segundos) y puede hacerse con código de hace 20 años. Dentro del código, también encuentran las claves criptográficas utilizadas para cifrar los datos de la empresa (¡es una práctica horrible almacenar las claves junto con el código fuente, pero le sorprendería la frecuencia con la que ocurre!) Si la empresa no se ha molestado en cambiar sus claves (al igual que las contraseñas), la misma clave puede utilizarse para causar estragos.
Como resultado, ha evolucionado la práctica de cambiar las claves con frecuencia. Esto se llama rotación de claves, y si está utilizando cualquier proveedor de PaaS en la nube respetable, debería estar disponible como un servicio automatizado.
Por ejemplo, AWS dispone de un servicio dedicado a ello llamado AWS Key Management Service (KMS). Un servicio automatizado le ahorra la molestia de cambiar y distribuir las claves entre todos los servidores y es una obviedad hoy en día cuando se trata de grandes despliegues.
Criptografía de clave pública
Si toda la charla anterior sobre cifrado y claves le hace pensar que es muy engorroso, está en lo cierto. Mantener las claves a salvo y transmitirlas de forma que sólo el receptor pueda ver los datos se enfrenta a problemas logísticos que no habrían permitido prosperar a las comunicaciones seguras de hoy en día. Pero todo gracias a la criptografía de clave pública, podemos comunicarnos o hacer compras en línea de forma segura.
Este tipo de criptografía supuso un gran avance matemático y es la única razón por la que Internet no se está desmoronando por el miedo y la desconfianza. Los detalles del algoritmo son intrincados y muy matemáticos, por lo que aquí sólo puedo explicarlo conceptualmente.
La criptografía de clave pública se basa en el uso de dos claves para procesar la información. Una de las claves se llama Clave Privada y se supone que debe permanecer privada con usted y nunca ser compartida con nadie; la otra se llama Clave Pública (de donde viene el nombre del método) y se supone que debe ser publicada públicamente. Si le estoy enviando datos, primero necesito obtener su clave pública y cifrar los datos y enviárselos; en su extremo, puede descifrar los datos utilizando su combinación de clave privada y clave pública. Mientras no revele accidentalmente su clave privada, puedo enviarle datos cifrados que sólo usted puede abrir.
Lo bueno del sistema es que no necesito conocer su clave privada, y cualquiera que intercepte el mensaje no puede hacer nada para leerlo aunque tenga su clave pública. Si se pregunta cómo es posible, la respuesta más breve y no técnica proviene de las propiedades de la multiplicación de los números primos:
Es difícil para los ordenadores factorizar números primos grandes. Así que, si la clave original es muy grande, puede estar seguro de que el mensaje no podrá ser descifrado ni siquiera en miles de años.
Seguridad de la capa de transporte (TLS)
Ahora ya sabe cómo funciona la criptografía de clave pública. Este mecanismo (conocer la clave pública del receptor y enviarle datos encriptados usando eso) es lo que está detrás de toda la popularidad de HTTPS y es lo que hace que Chrome diga: «Este sitio es seguro» Lo que ocurre es que el servidor y el navegador están cifrando el tráfico HTTP (recuerde, las páginas web son cadenas de texto muy largas que los navegadores pueden interpretar) con las claves públicas del otro, lo que da como resultado HTTP seguro (HTTPS).
Crédito de la imagen: MozillaEs interesante observar que la encriptación no se produce en la capa de transporte como tal; el modelo OSI no dice nada sobre la encriptación de datos. Simplemente, los datos son encriptados por la aplicación (en este caso, el navegador) antes de pasar a la Capa de Transporte, que posteriormente los deja en su destino, donde son desencriptados. Sin embargo, el proceso implica a la Capa de Transporte y, al final, todo resulta en un transporte seguro de los datos, por lo que el término suelto de seguridad de la capa de «transporte» se ha quedado.
Puede que incluso se encuentre con el término Capa de sockets seguros (SSL ) en algunos casos. Es el mismo concepto que TLS, salvo que SSL se originó mucho antes y ahora ha pasado a mejor vida en favor de TLS.
Cifrado de disco completo
A veces las necesidades de seguridad son tan intensas que no se puede dejar nada al azar. Por ejemplo, los servidores gubernamentales donde se almacenan todos los datos biométricos de un país no pueden aprovisionarse y ejecutarse como servidores de aplicaciones normales, ya que el riesgo es demasiado alto. Para estas necesidades no basta con que los datos se cifren sólo cuando se transfieren; también tienen que cifrarse cuando están en reposo. Para ello, se utiliza el cifrado de disco completo para cifrar la totalidad de un disco duro con el fin de garantizar que los datos estén seguros incluso cuando son violados físicamente.
Es importante tener en cuenta que la encriptación de disco completo tiene que hacerse a nivel de hardware. Esto es así porque si ciframos todo el disco, el sistema operativo también se cifrará y no podrá ejecutarse cuando se inicie la máquina. Así pues, el hardware tiene que entender que el contenido del disco está cifrado y debe realizar el descifrado sobre la marcha cuando pasa los bloques de disco solicitados al sistema operativo. Debido a este trabajo extra que se realiza, la encriptación de disco completo da lugar a lecturas/escrituras más lentas, lo que deben tener en cuenta los desarrolladores de este tipo de sistemas.
Cifrado de extremo a extremo
Con las continuas pesadillas sobre la privacidad y la seguridad de las grandes redes sociales en la actualidad, nadie ignora el término «cifrado de extremo a extremo», aunque no tenga nada que ver con la creación o el mantenimiento de aplicaciones.
Antes vimos cómo el cifrado de disco completo proporciona la estrategia definitiva a prueba de balas, pero para el usuario cotidiano no es conveniente. Es decir, imagine que Facebook quiere que los datos telefónicos que genera y almacena en su teléfono estén seguros, pero no puede tener acceso a cifrar todo su teléfono y bloquear todo lo demás en el proceso.
Por esta razón, estas empresas han puesto en marcha la encriptación de extremo a extremo, lo que significa que los datos se encriptan cuando son creados, almacenados o transferidos por la aplicación. En otras palabras, incluso cuando los datos llegan al destinatario, están totalmente encriptados y sólo son accesibles por el teléfono del destinatario.
Tenga en cuenta que el cifrado de extremo a extremo (E2E) no conlleva ninguna garantía matemática como la criptografía de clave pública; se trata simplemente de un cifrado estándar en el que la clave se almacena con la empresa, y sus mensajes son tan seguros como la empresa decida.
Conclusión 👩🏫
Es probable que ya haya oído hablar de la mayoría de estos términos. Puede que incluso de todos ellos. Si es así, le animo a revisar su comprensión de estos conceptos, así como a realizar una evaluación de la seriedad con la que se los toma. Recuerde que la seguridad de los datos de las aplicaciones es una guerra que debe ganar siempre (y no sólo una vez), ya que una sola brecha es suficiente para destruir industrias enteras, carreras profesionales e incluso vidas