martes, 28 de julio de 2020

Criptografía en Python - AES

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

¿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

No hay comentarios :
Write comentarios

Tu comentario es importante y nos motiva a seguir escribiendo...

Powered by Blogger .