Criptografía en Python - AES

Junto con
Joan Daemen, Vincent Rijmen diseñó el algoritmo de cifrado
Rijndael, que fue seleccionado como AES en
2000
Índice

¿Qué es AES?

AES (Advanced Encryption Standard, en inglés), también
conocido como Rijndael (pronunciado "Rain Doll" en inglés), es un
esquema de cifrado por bloques adoptado como un estándar de cifrado por el
gobierno de los Estados Unidos, creado en Bélgica. Se transformó en un
estándar efectivo el 26 de mayo de 2002. Desde 2006, el AES es uno de los
algoritmos más populares usados en criptografía simétrica.
El cifrado fue desarrollado por dos criptólogos belgas, Joan Daemen y
Vincent Rijmen, y fue enviado al proceso de selección AES bajo el
nombre "Rijndael", como parte de un concurso.

AES y sus modos de cifrado

AES no es un simple algoritmo que se le pasa un dato de entrada y te
devuelve uno salida, él funciona con modos de operación los cuales son
varios, pero aquí una pequeña lista de los muchos que podríamos usar:
  • Cipher-block chaining (CBC):
    En el modo cipher-block chaining (CBC), a cada bloque
    de texto plano se le aplica la operación
    XOR
    con el bloque cifrado anterior antes de ser cifrado. De esta
    forma, cada bloque de texto cifrado depende de todo el texto
    en claro procesado hasta este punto. Para hacer cada mensaje
    único se utiliza asimismo un vector de inicialización.

  • Counter (CTR): Al igual que OFB, el modo contador convierte una unidad de
    cifrado por bloques en una unidad de flujo de cifrado. Genera el
    siguiente bloque en el flujo de claves cifrando valores
    sucesivos de un contador. El contador puede ser cualquier
    función sencilla que produzca una secuencia de números donde los
    resultados se repiten con muy baja frecuencia. Si bien la
    operación más usada es un contador, el modo CTR tiene
    características similares al OFB, pero permite también usar una
    propiedad de acceso aleatorio para el descifrado.

  • Electronic Code-Book (ECB): El más sencillo es el modo electronic codebook (ECB), en el
    cual los mensajes se dividen en bloques y cada uno de ellos es
    cifrado por separado utilizando la misma clave K. La desventaja de
    este método es que a bloques de texto plano o claro idénticos les
    corresponden bloques idénticos de texto cifrado, de manera que se
    pueden reconocer estos patrones como guía para descubrir el texto en
    claro a partir del texto cifrado. De ahí que no sea recomendable
    para protocolos cifrados.
  • Galois/Counter Mode (GCM): En criptografía,
    Galois/Counter Mode (GCM) es un modo de operación
    para los cifrados de bloques criptográficos de clave simétrica
    ampliamente adoptados para su rendimiento.
    Las tasas de rendimiento de GCM para canales de comunicación de
    alta velocidad de última generación se pueden lograr con
    recursos de hardware económicos. 
    La operación es un
    algoritmo de cifrado autenticado diseñado para proporcionar
    autenticidad de datos (integridad) y confidencialidad.
    GCM se define para cifrados de bloques con un tamaño de bloque
    de 128 bits.
    Galois Message Authentication Code (GMAC) es una
    variante de autenticación solamente del GCM que puede formar un
    código de autenticación de mensajes incremental.
    Tanto GCM como GMAC pueden aceptar vectores de inicialización
    de longitud arbitraria.

La lista puede seguir y seguir, pero lo importante es elegir uno que
se acople mejor a la situación, que sea seguro y eficiente.

AES en python

Ya hemos visto lo que puede hacer la librería pycryptodome en
el
artículo anterior, pero no hemos explotado todo lo que nos ofrece, entre ello está
la posibilidad de usar AES.
En este tutorial crearemos dos funciones, una para cifrar y otra
para descifrar usando el modo EAX.
Primero importamos el módulo AES:
from Crypto.Cipher import AES

Ahora creamos la función para encriptar:
def encrypt(key, data):
    cipher = AES.new(key, AES.MODE_EAX)
    ciphertext, tag = cipher.encrypt_and_digest(data)

    return cipher.nonce + tag + ciphertext
Muy bien, una vez hemos creado la función para encriptar necesitamos
comprender cada parámetro, variables y demás dato que nos sea de
utilidad.
Lo primero que hay que saber, es que key es la clave,
contraseña, etc, con la que queramos cifrar los datos, mientras que
data son los datos a cifrar. Cada uno de ellos debe ser de
tipo bytes, aunque ya lo veremos detenidamente en una breves
instantes.
La variable ciphertext es la que hace referencia al resultado
de los datos cifrados; tag es el código de autenticación de
mensajes (MAC) calculado durante el cifrado. Y por último pero no
menos importante el nonce (number occuring once [número que
ocurre una vez, en español]), también conocido como el vector de
inicialización, el cual es un número aleatorio que se utiliza para
mejorar la aleatorización.
Ahora creamos la función para desencriptar:
def decrypt(key, data):
    nonce = data[:AES.block_size]
    tag = data[AES.block_size:AES.block_size * 2]
    ciphertext = data[AES.block_size * 2:]

    cipher = AES.new(key, AES.MODE_EAX, nonce)
    
    return cipher.decrypt_and_verify(ciphertext, tag)
Lo primero que hay que saber, es que necesitamos calcular todo lo que el destinatario nos ha enviado. En el caso del nonce ímplicitamente estamos colocando un índice del 0-16 (la constante block_size del módulo AES vale 16), es recomendable usar la constante explícitamente en vez del número que conozcamos. Ya partiendo con el siguiente dato deseado, el tag, que ahora debe comenzar con un índice de 16-32 y por último, ciphertext con un índice de 32-[Hasta el último dato].

De la teoría a la práctica

Ya hemos presenciado lo más trivial de la usabilidad de AES en python gracias a la disposición de la librería pycryptodome, pero ahora pongamos en práctica lo que hemos creado con tanto esfuerzo. Llamaremos a todo lo que hemos escrito aes.py (o como deseamos), importemoslo y vamos a usarlo directamente, todo desde la consola de python:
Cifrando y descifrando desde la consola de python
El código de nuestro módulo para cifrar/descifrar datos usando AES

Lecturas recomendadas:

Todo lo que hemos y veremos son cosas sumamente básicas, son más introductorias que de enseñanza avanzada, realización hecha con esa metodología porque ayudará a las personas más noveles a adentrarse con el pie derecho en la criptografía, en la implemetación o por lo menos en la creación de aplicaciones seguras. La criptografía no es un juego, es muy fácil cometer errores que pueden costar caro, por lo que recomiendo leer más allá de lo que sea plantea en este diminuto artículo. En este caso les recomiendo las siguientes lecturas:
  • https://pycryptodome.readthedocs.io
  • https://pycryptodome.readthedocs.io/en/latest/src/examples.html#encrypt-data-with-aes
  • https://es.wikipedia.org/wiki/Cifrado_por_bloques
  • https://en.wikipedia.org/wiki/Initialization_vector
  • http://blog.cryptographyengineering.com/2012/05/how-to-choose-authenticated-encryption.html
~ DtxdF

Deja una respuesta

Tu dirección de correo electrónico no será publicada. Los campos obligatorios están marcados con *

Subir
White Monkey