Cifrado simétrico por bloques

Publicado por Diego Córdoba en

Hoy vamos a adentrarnos en el cifrado simétrico por bloques y la forma con la que los cifradores simétricos encadenan dichos bloques durante la encriptación.

Este artículo forma parte de la Serie sobre Criptografía Aplicada publicada en este blog. Pueden visitar el índice de la serie para acceder a todo el contenido.

Partimos del artículo anterior, en el que introdujimos los conceptos básicos sobre cómo lograr la seguridad utilizando cifrado simétrico y funciones hash. Hablamos de seguridad en términos de confidencialidad, autenticidad e integridad.

Si bien existen numerosos modos de operación de los principales cifradores simétricos de bloque, en este artículo comentaré los principales. Esto permitirá entender las cipher suites, o conjuntos de algoritmos utilizados por herramientas como OpenSSL para lograr seguridad.

Modos de operación de cifrado simétrico por bloques

Los algoritmos de cifrado simétrico por bloques dividen el texto plano en bloques de igual tamaño, y luego los encriptan, generando una serie de bloques cifrados.

Antes, algunas aclaraciones sobre los diagramas que se ven a continuación:

  • M1, M2, etc. hace referencia a bloques de texto plano.
  • C1, C2, etc. hace referencia a bloques de texto cifrado.
  • E: se refiere a tareas de encriptación del algoritmo.
  • D: hace referencia a tareas de desencriptación.
  • La llave que se ve en los diagramas representa la clave simétrica, y es la misma clave usada para encriptar y desencriptar.
  • IV: hace referencia a un bloque aleatorio generado para su uso en algunos modos de operación (Vector de Inicialización – Initialization Vector).
  • El símbolo representa la operación XOR bit a bit entre dos entradas.

Veamos algunos ejemplos de modos de operación comunes, con ventajas y desventajas de cada uno.

ECB – Electronic Code Book

Este es el modo de operación más simple. Aquí, para realizar el cifrado, se divide al texto plano en bloques, y se encripta cada bloque por separado. Luego se obtiene el texto cifrado concatenando todos los bloques cifrados obtenidos.

La tarea de desencriptación es similar.Se descifra bloque por bloque utilizando la primitiva de descifrado, junto con la clave simétrica, obteniendo cada bloque de texto plano.

ecb cifrado por bloques

Este modo es paralelizable, es decir, permite encriptar/desencriptar diferentes bloques en paralelo. Esto le da mejor rendimiento que otros modos.

El inconveniente es que, para el mismo texto plano, el cifrador genera el mismo texto cifrado. Si bien bloque por bloque no representa un problema, el conjunto de datos puede entregar información al atacante. Veamos un ejemplo para entenderlo mejor.

Supongamos que tenemos una imagen, y cada pixel representa un bloque de datos. Si encriptamos la imagen usando cifrado simétrico por bloques en modo ECB, obtendremos un archivo cifrado, eso está claro.

No obstante, como a igual texto plano se genera el mismo texto cifrado, los pixeles de igual color en la imagen original tendrán igual color en la imagen cifrada (será otro color, por supuesto, pero será el mismo para todos los pixeles iguales).

Un pequeño experimento

Para que tengan una idea de lo que comento, les comparto un pequeño experimento que hice con openssl (herramienta que analizaremos en otro artículo práctico).

El experimento consistió en tomar la imagen de los párrafos anteriores, y:

  1. Creé una imagen en formato PPM para facilitar la visualización. Es un formato que no posee compresión, y cuya cabecera tiene formato ASCII, y especifica las dimensiones, en pixeles, de la imagen, y la profundidad de color. Reservé la cabecera para usarla luego.
  2. Encripté la imagen PPM usando un cifrador simétrico en modo ECB (particularmente DES). El archivo cifrado es binario y es totalmente ilegible.
  3. Finalmente tomé la cabecera de la imagen original, que identifica formato PPM y sus características, y la pegué encima del código binario de la imagen cifrada. Eso hace que los visores de imágenes la identifiquen como una imagen PPM cualquiera.

No incluí los comandos que usé para llevar a cabo el experimento porque se extendía mucho el artículo. Si les interesa no tienen más que escribirme y publico un artículo al respecto.

La imagen original es esta:

La imagen encriptada, si bien bloque por bloque es totalmente ilegible, el conjunto completo no dice lo mismo 😛

imagen cifrada con ecb

Se dice que este método carece de difusión. La difusión es una propiedad de los algoritmos criptográficos que implica modificar la mayor cantidad posible de bits del texto cifrado al cambiar un bit del texto plano.

CBC – Cipher Block Chaining

Este modo de operación encadena el cifrado de cada uno de los bloques mediante operaciones XOR. En este caso, a cada bloque de texto plano se le realiza una operación XOR con el bloque cifrado anterior, y a su resultado se lo encripta usando la primitiva de cifrado y la clave simétrica. El bloque cifrado generado servirá para la siguiente operación de encriptación.

Esto requiere que se añada un vector de inicialización, o IV (initialization vector) aleatorio para realizar el XOR con el primer bloque de texto plano, ya que no posee bloque cifrado anterior.

La siguiente figura muestra el proceso. El símbolo representa la operación XOR.

cbc cifrado por bloques

La tarea de desencriptación es a la inversa: a cada bloque cifrado se lo desencripta utilizando la clave privada y la operación de descifrado del algoritmo, y a su resultado se lo pasa por un XOR con el bloque cifrado anterior (o el IV si se trata del primer bloque cifrado) para obtener el texto plano original (recordemos la propiedad de simetría del XOR).

La ventaja de este modo (y de todos los demás) es que genera diferentes bloques cifrados para dos bloques de texto plano iguales, lo que incrementa la difusión del algoritmo. Como desventaja, la encriptación en este modo no es paralelizable, por lo que el procesamiento es secuencial.

CFB – Cipher Feedback

Este modo es un tanto particular: genera bloques cifrados sin encriptar directamente el texto plano original 😛

Primero se toma el bloque cifrado anterior (si hablamos del primer bloque de texto plano, se incorpora un IV). A dicho bloque se lo encripta utilizando el algoritmo y la clave privada. Al bloque resultante, llamémosle «bloque intermedio«, se le realiza una operación XOR con el bloque de texto plano, obteniendo el bloque cifrado.

Dicho bloque cifrado se utilizará en el XOR para generar el siguiente bloque.

Veamos un diagrama para entenderlo mejor.

cfb cifrado por bloques

La tarea de desencriptación es similar. Se toma el bloque anterior, se lo encripta utilizando el algoritmo y la clave, y al resultado se lo opera usando XOR con el bloque cifrado, obteniendo nuevamente el texto plano. Sí, dije «encripta«, ya que esto permite obtener el texto plano gracias nuevamente a la propiedad de simetría de la operación XOR.

Este modo no es paralelizable, ya que para realizar al operación de XOR que genera un bloque cifrado se requiere el bloque cifrado anterior.

OFB – Output Feedback

Este modo es similar al anterior. La diferencia radica en que la operación XOR se realiza entre el bloque de texto plano y el bloque intermedio anterior, nuevamente cifrado. Veamos un diagrama que lo explica más fácilmente.

ofb cifrado por bloques

Técnicamente se dice que este modo realiza una operación XOR entre cada bloque de texto plano y cada bloque de un KeyStream. El KeyStream es un conjunto de datos pseudo-aleatorios generados con el propósito de combinarse con bloques de texto plano para obtener el texto cifrado.

En este caso el keystream es una secuencia de bloques cifrados sucesivamente a partir de un IV pseudo-aleatorio inicial.

Este modo, al igual que el anterior, tampoco es paralelizable, pero sí puede pre-calcularse el keystream, a partir del IV, y luego paralelizar las operaciones de XOR con cada uno de los bloques de texto plano o texto cifrado, ya sea para encriptar o desencriptar respectivamente. Este pre-cálculo no era posible utilizando el modo CFB.

La tarea de desencriptación es similar. Partiendo del IV, se genera el keystream de bloques cifrados, y cada uno de estos bloques es operado, mediante XOR, con los bloques de texto cifrado, obteniendo los bloques de texto plano originales (de nuevo, gracias a la propiedad de simetría del XOR).

CTR – Counter

Este modo podría decirse que es una evolución del OFB. Aquí, en lugar de utilizar una keystream a partir del IV, lo que se encripta en cada operación de cifrado, previo a realizar el XOR con el texto plano, son bloques compuestos por un nonce (un valor pseudo-aleatorio igual para todos los bloques, similar a un IV) concatenado con un contador que se incrementa con cada bloque.

Una imagen vale mas que mil palabras:

ctr cifrado por bloques

De esta manera se logra el efecto de un modo OFB, pero a la vez permite paralelizar las operaciones de cifrado y XOR que generan cada bloque de texto cifrado.

La tarea de desencriptación es similar.Para obtener cada bloque de texto plano se utiliza el mismo nonce concatenado con el contador según el número de bloque que se trate. Este nonce+contador se encripta, y su resultado es operado mediante XOR con el bloque de texto cifrado, obteniendo el texto plano original, gracias a la propiedad de simetría de la operación XOR.

Existe un modo derivado de CTR denominado GCM. GCM (Galois/Counter Mode) combina la confidencialidad de los bloques cifrados del modo CTR, con el método de autenticación de Galois. Esto permite un mecanismo de cifrado autenticado.

Es importante mencionarlo como ejemplo de que algunos modos más complejos pueden verificar autenticidad junto con la confidencialidad, pero no voy a extenderme porque excede los alcances de este artículo. Si les interesa, en otra oportunidad amplío detalles.

Conclusiones: cifrado simétrico por bloques

Hemos hecho revisión de los principales modos de operación de los algoritmos simétricos.

Existen otros modos, pero conociendo los principales, y el funcionamiento interno de los mismos, no debería resultar un impedimento aprender nuevos modos de operación.

Para que tengamos una idea de las cipher suites que incorpora OpenSSL, les comparto un extracto de la lista de cifradores disponibles, y el comando que usé para obtenerla:

En el próximo artículo aprenderemos a utilizar openssl para encriptar y desencriptar archivos de manera simétrica, y para calcular HMAC.

Espero que les resulte interesante!

Hasta la próxima!


¿Preguntas? ¿Comentarios?

Si tenés dudas, o querés dejarnos tus comentarios y consultas, sumate al grupo de Telegram de la comunidad JuncoTIC!
¡Te esperamos!


Diego Córdoba

- Ingeniero en Informática - Mg. Teleinformática - Tesis pendiente - Docente universitario - Investigador