(Encontré un hilo en Twitter con una muy buena explicación de las cifras simétricas. Fue escrito por Colm MacCárthaigh, uno de los principales contribuyentes de Apache. Le pedí permiso a Colm para traducir, él estuvo de acuerdo amablemente).
Te explicaré en un lenguaje sencillo lo que sucede cuando los datos están encriptados. Espero que sin el misticismo y las cosas complejas que inventaron los criptógrafos.
Entonces, el cifrado simétrico es exactamente lo que usamos en la mayoría de los casos cuando queremos cifrar un montón de datos. Su navegador envía y recibe datos mediante cifrado simétrico. Si cifra archivos o un disco, el cifrado simétrico también funciona en este caso. iMessage, Signal, WhatsApp: todos utilizan cifrado simétrico para la seguridad de su correspondencia.
Si cree que al cifrar los datos se mezclan para que nadie pueda leerlos sin una clave, la forma en que realmente sucede.
Aquí hay un ejemplo simple. Supongamos que tengo una cadena Ovaltine y quiero encriptarla. Podría usar rot13: el cifrado muy simple de la vieja escuela de César, que hace un baile redondo de letras donde a y z se toman de la mano, y reemplaza cada letra con otra letra del alfabeto, que son 13 caracteres de la letra reemplazada. Por lo tanto, "O" se convierte en "B", y "v" se convierte en "i", como resultado, "Ovaltine" se convierte en "Binygvar". Por supuesto, esto no es muy seguro. Este es un ejemplo ingenuo, que es muy fácil de descifrar, ya que el atacante puede averiguar qué letra se encuentra con mayor frecuencia (generalmente en el texto original es "e") y encontrar las letras restantes de esta manera.
Ahora puede imaginar que debería haber formas más difíciles de "mezclar" las letras. Por ejemplo, algún esquema complejo en el que "a" va a "p", pero cuando se vuelve a cifrar, a "f". Quizás incluso a veces este esquema comienza a encriptar "a" con dos letras, por ejemplo, "jd" u otra cosa. Por lo tanto, este complicado esquema puede encriptar "Ovaltine" en la cadena "FGyswDmweeRq" (tenga en cuenta que se ha vuelto más largo). Los algoritmos de cifrado aparecieron en el pasado que funcionaban de manera similar, pero no es así como funciona el cifrado moderno.
En lugar de "barajar" letras, el cifrado moderno toma su cadena secreta y la combina ingeniosamente con datos aleatorios. Esto es similar a rot13 solo en dos aspectos: el cifrado y el descifrado son esencialmente la misma operación, y todo sucede "en su lugar". De hecho, ¿has notado que rot13 es un algoritmo de cifrado y descifrado? rot13 (Ovaltine) -> Binygvar, rot13 (Binygvar) -> Ovaltine. Creo que esta es una simetría muy hermosa en el cifrado simétrico. Pero volvamos a nuestro tema. El truco es que usamos la operación XOR bit a bit. En criptografía, lógica formal y código, los programas XOR se pueden definir de manera diferente, pero utilizaré una notación con la que probablemente esté familiarizado. Se ve así: ^.
XOR significa "OR exclusivo". Este es un operador (o función, si lo prefiere), que toma dos argumentos y devuelve el resultado. A ^ B = C. Este operador se llama "bit a bit" porque se aplica a los bits que se corresponden entre sí. Si A y B son bytes, entonces podemos suponer que A ^ B = C son esencialmente 8 operaciones diferentes que ocurren simultáneamente. ^ compara el primer bit A y el primer bit B, y luego coloca el resultado en el primer bit C. Repite las mismas 7 veces más para los bits restantes. Las reglas son simples: si el bit de A es "1" O el bit de B es "1", entonces configuramos el bit C correspondiente a "1", pero solo si "A" y "B" no son "1" al mismo tiempo. Esta es la parte exclusiva. Aquí hay una tabla de verdad de la vieja escuela:
A|B|C 0|0|0 1|0|1 0|1|1 1|1|0
Lo mejor de XOR es que parece podrido13. Podemos usarlo para el cifrado y descifrado. Mostraré esto con un simple ejemplo. Imaginemos que queremos cifrar el número habitual "3" y que nuestra clave de cifrado es otro número "7". Por lo tanto, 3 ^ 7 = 4. Es decir, el resultado del cifrado es "4". Ahora descifremos el número. Simplemente haré lo mismo otra vez: 4 ^ 7 = 3. Tome cualquier número que desee o cualquier dato, y siempre funcionará: XOR siempre podrá descifrarse.
Poco a poco: así es como realmente ciframos y desciframos los datos, no hay mezcla, solo XOR. La parte difícil es encontrar datos a los que podamos aplicar XOR. Un enfoque es tomar una gran cantidad de datos secretos a la mano y usarlos como el segundo argumento para XOR. En este caso, todos los participantes en el proceso de transmisión de datos cifrados deben usar el mismo conjunto de datos secretos para el cifrado y descifrado. Y funcionará. Es cierto que hay varios problemas.
El primer problema Los datos secretos deberían parecer aleatorios. No puedes tomar texto de un libro ni nada de eso. Cualquier patrón aparecerá en los datos cifrados. Esto es precisamente lo que hizo que las fuerzas aliadas fueran superiores en la Segunda Guerra Mundial.
El segundo problema No puede reutilizar datos confidenciales, ya que reaparecerán los patrones. Por lo tanto, de alguna manera tiene que proporcionar grandes cantidades de datos secretos para todos los que lo necesitan, como el pad de una sola vez. Esto es muy dificil.
En el cifrado moderno, "generamos" los datos secretos que necesitamos a partir de claves pequeñas. Estas llaves son mucho más fáciles de transportar y proteger. Esto es lo que realmente son los algoritmos de cifrado simétrico: esquemas para la generación determinista de datos aleatorios a partir de una clave. La parte sobre el "determinismo" es muy importante: dos personas con la misma clave deben generar absolutamente el mismo conjunto de datos, de lo contrario no podrán entenderse. Probablemente haya escuchado acerca de tales algoritmos: AES, 3DES, DES, RC4, ChaCha20. Todos lo hacen
Resulta que el problema matemático de generar un flujo de datos aleatorio (en el que no hay patrones en ninguna forma predecible) usando la clave es muy difícil. De esta lista, solo AES y ChaCha20 se consideran seguros hoy en día. Se piratearon otros algoritmos: las personas pudieron predecirlos. Además, AES tiene una reputación ligeramente empañada, porque los criptógrafos dicen lo siguiente:
AES es el algoritmo de cifrado principal y más analizado. Absolutamente Gold Standard! : dark_sunglasses:
Pero al mismo tiempo agregan:
Las implementaciones de AES en software (no en hardware) son inseguras o lentas, y algunas veces no son seguras y lentas. No fue diseñado teniendo en cuenta el hecho de que puede ser pirateado mediante el análisis de caché. : facepalm:
No tengas miedo si esto no te resulta claro. La idea principal es esta: AES es magnífico desde el punto de vista de las matemáticas, pero es muy complicado en la implementación de software. Pero no se preocupe: casi siempre tenemos soporte AES a nivel de hardware (puede encontrar una lista de todos los procesadores con soporte de hardware AES aquí https://en.wikipedia.org/wiki/AES_instruction_set , - nota del traductor).
Sea como fuere, continuamos ... ¿Cómo funcionan realmente estos algoritmos? ¿Cómo podemos tomar una clave y generar de forma segura un flujo de datos aleatorio? Aquí simplificaré un poco las cosas y comenzaré con bloques.
Estos algoritmos reciben tres parámetros en la entrada y dan el texto cifrado en la salida. Parámetros de entrada - una clave, texto cifrado y ... sorpresa - algo extraño llamado "vector de inicialización" (vector de inicialización, IV).
AES(key, IV, plaintext) -> encrypted_data.
La clave y el IV se combinan entre sí para crear un conjunto de "condiciones de inicio" para el algoritmo; Esto es similar al intercambio inicial o al barajado de fichas en un juego de Scrabble. La misma combinación de tecla y IV siempre creará el mismo conjunto de condiciones de inicio. Usted pregunta, ¿por qué necesitamos IV entonces? Necesitamos un IV para poder encriptar múltiples mensajes usando la misma clave. Sin IV, cada flujo de datos generado sería el mismo, y esto es malo. Esto violaría una de las reglas de las que hablamos anteriormente: no podemos reutilizar los mismos datos para el cifrado. Entonces necesitamos una vía intravenosa para mezclar el resultado. Pero a diferencia de la clave IV, puede ser pública.
Entonces, cuando encriptas un mensaje y se lo envías a alguien, también puedes agregar: "Hola, aquí está el IV que usé". Todavía es crítico que no reutilicemos la combinación de clave y IV, porque nos darían datos aleatorios repetidos. Hay dos formas de lograr esta condición: 1) IV es un tipo de contador que aumentamos con cada nuevo mensaje. 2) IV se genera aleatoriamente, mientras que tiene un valor bastante grande, por lo que no debemos preocuparnos mucho por las colisiones. Sea como fuere, mencioné que hablaré sobre bloques.
Las teclas y IV están "mezcladas" o combinadas de tal manera que crean un conjunto de condiciones de inicio ... estas condiciones son en realidad el "bloque" inicial de datos aleatorios. La longitud de este bloque es de 128 bits para AES128, 256 bits para AES256 y 512 bits para ChaCha20. Y aquí se manifiesta la verdadera magia e individualidad de un algoritmo de cifrado particular. De hecho, su esencia radica en cómo se genera la secuencia de bloques y cómo cada bloque está asociado con sus vecinos. La relación entre estos bloques sigue siendo predecible incluso para aquellos que no tienen una clave.
No profundizaré en cómo funcionan estos algoritmos, pero si desea saber más, le aconsejo que comience a explorar este tema con los generadores congruenciales lineales (LCG). LCG es una función que crea bloques de datos "circulares" de forma aleatoria y no repetitiva. Luego eche un vistazo a las redes Feistel, el siguiente nivel de desarrollo de LCG. Luego trate con S-Boxes, y luego mire cómo Salsa20 crea entrelazado en el algoritmo ChaCha20. ¡Todo esto es mucho más asequible de lo que piensas!
Entonces, ahora sabemos cómo se puede combinar un flujo de datos aleatorio con texto para cifrarlo y descifrarlo, y ya estamos un poco en el tema de cómo se crean estos flujos de datos aleatorios. ¿No es eso todo lo que necesitamos? Para el cifrado de disco, eso es realmente casi todo. Podemos encriptar cada bloque o sector del almacenamiento usando una clave y IV, que se puede obtener desde la "posición" en el disco. Por lo tanto, siempre podemos descifrar cualquier bloque de datos en cualquier parte del disco, siempre que tengamos la clave. Pero hay un problema ... alguien puede arruinar nuestros datos cifrados. Si cambio el valor de cualquier byte, incluso si no tengo una clave, al final no podremos descifrar el bloque. Y no hay protección contra este tipo de interferencia. En el caso de enviar mensajes y datos a través de la red, esto se vuelve aún más crítico. No queremos que nadie estropee nuestros datos transmitidos. ¡Entonces necesitamos agregar una verificación de integridad! Hay varios esquemas para hacer esto.
HMAC, GCM y Poly1305 son los esquemas de comprobación de integridad modernos más comunes. Básicamente, estos algoritmos funcionan así: se suministran con datos y otra clave (la llamada clave de integridad). Después de los cálculos, entregan el MAC (código de autenticación del mensaje) o la etiqueta, que a su vez es solo otra pieza de datos que actúa como una firma.
Por lo tanto, para el cifrado y la protección, nuestro esquema puede verse así:
AES(key, IV, "Ovaltine") -> encrypted_output HMAC(key, encrypted_output) -> MAC
y luego por cable enviamos:
IV | encrypted_output | MAC
Para el descifrado, verificamos el MAC, lo generamos nuevamente y comparamos el resultado con el MAC recibido, y luego desciframos los datos. Existen diferencias internas en cómo HMAC, GCM y Poly1305 generan estas firmas, pero no tiene que preocuparse por eso. Hasta la fecha, esta combinación de operaciones generalmente está envuelta en una función llamada "AEAD" (Cifrado autenticado con datos adicionales). Debajo del capó, ella hace todo lo que hablé antes:
AEAD(key, IV, plaintext, additional_data) -> IV_encrypted_data_MAC
Una pieza llamada "datos_adicionales" son solo datos con los que puede asegurarse de que la parte remitente tenga estos datos, aunque no se los envió. Es como los metadatos que establecen los derechos de acceso. A menudo, este campo se deja en blanco.
Sin embargo, puede tener problemas con AEAD si usa el mismo IV. Esto es malo! Hay intentos de mejorar esta situación: mi colega, cuyo nombre es Shay, está trabajando en un genial esquema SIV que agrega una capa de protección contra este problema. Pero si usa un IV único, el cifrado moderno es muy seguro. Es decir, puede publicar el texto cifrado en el New York Times, y nadie puede descifrarlo. El cifrado permanecerá inaccesible incluso si se conoce "alguna" parte del texto. Por ejemplo, en los protocolos de Internet se conoce una gran cantidad de texto. Los servidores HTTP siempre responden igual y siempre se conocen los primeros bytes. Pero este hecho no importa en absoluto: no ayudará al atacante a encontrar una sola pieza de los datos restantes ... Hemos recorrido un largo camino desde la Segunda Guerra Mundial.
¡Pero hay ataques que funcionan! Si envía datos a través de una red y alguien rastrea el tiempo y el tamaño de los mensajes, los datos cifrados pueden descifrarse mediante el análisis de tráfico.

Vamos a averiguar la longitud primero. Obviamente, la longitud no es una característica oculta. Y esto es normal si está tratando de proteger su contraseña o número de tarjeta de crédito en algún lugar en el medio del mensaje. No es un gran problema Pero esto significa que potencialmente cualquier persona puede determinar el tipo de contenido que envía. Un ejemplo simple: si envía un gif usando un messenger y si el tamaño de esta imagen es único, el atacante que intercepta sus datos puede sugerir qué GIF se acaba de enviar. Hay versiones más complicadas de este ataque para Google Maps, Netflix, Wikipedia, etc. Para protegerse contra este ataque, puede "terminar" los mensajes enviados con bytes adicionales, de modo que todos los mensajes enviados tengan la misma longitud, pase lo que pase. El cifrado utilizado en las redes militares siempre "termina" el tráfico con datos adicionales, es decir, ¡para el interceptor siempre se ve igual! Otro problema asociado con la longitud es que si usa la compresión y le da al atacante la capacidad de cambiar cualquier parte del contenido de la página que ve el usuario, esto le permite al atacante descubrir incluso los secretos más pequeños. Busca un ataque llamado CRIMEN. Ella es hermosa y aterradora.
También dije que el otro problema es el tiempo. Obviamente, el tiempo de envío de cada mensaje es información abierta. ¿Podría ser esto un problema? Tal vez! Por ejemplo, si envía un mensaje cada vez que presiona una tecla, es trivial averiguar qué se imprime exactamente mediante el análisis de tiempo. Genial! Otro ejemplo es VOIP. Si su aplicación de llamada envía datos solo cuando las personas hablan, pero no durante el silencio, esto es suficiente para restaurar el 70% del habla en inglés. Solo por el silencio. Miedo genial.
Estos ejemplos son solo la punta del iceberg. Incluso cuando usa algoritmos y esquemas de encriptación que han estado mejorando durante 80 años, todavía hay brechas que pueden usarse para romper la seguridad. ¡Por eso es valioso saberlo!
Sea como fuere, este es el nivel de explicación en el que quiero detenerme ahora, pero hemos considerado las cosas más necesarias para saber. Si lees hasta este punto, ¡gracias! Ahora debe tener una mejor comprensión de lo que sucede durante el cifrado y de lo que debe tener cuidado.
Siéntase libre de hacer preguntas.
La traducción se publica bajo la licencia CC BY-NC-SA 4.0