Ir al contenido principal

Criptografía en Python con PyCrypto

A la hora de cifrar información con Python, tenemos algunas opciones, pero una de las más fiables es la librería criptográfica PyCrypto, que soporta funciones para cifrado por bloques, cifrado por flujo y cálculo de hash. Además incorpora sus propios generadores de números aleatorios. Seguidamente os presento algunas de sus características y también como se usa.



Los cifrados por bloque soportados por PyCrypto son:
AES
ARC2
Blowfish
CAST
DES
DES3
IDEA
RC5

Los cifradores de flujo soportados son:
ARC4
XOR

En general, todos estos cifradores se usan de la misma manera:

Importación del módulo.
from Crypto.Cipher import [Tipo_Cifrador]

Creación del cifrador.
New ([clave], [modo], [Vector IV])

Sólo la clave es obligatoria, y habrá que tener en cuenta si el tipo de cifrado exige que tenga un tamaño concreto.
Los modos posibles son MODE_ECB, MODE_CBC, MODE_CFB, MODE_PGP, MODE_OFB, MODE_CTR, MODE_OPENPGP.

Si se utilizan los modos MODE_CBC o MODE_CFB, hay que inicializar el tercer parámetro (Vector IV) que permite dar un valor inicial al cifrador.
Algunos cifradores pueden tener parámetros opcionales, como por ejemplo, AES, que puede especificar el tamaño de bloque y de clave con los parámetros block_size y key_size.

Cifrado / Descifrado.
Para cifrar se usa la función encrypt:
encrypt('texto en claro')

Para descifrar se usa decrypt:
decrypt('texto cifrado')

En cuanto a las funciones Hash, son soportadas son las siguientes:
MD2
MD4
MD5
RIPEMD
SHA1
SHA256

El uso de general de las funciones hash es también sencillo:

Importación del módulo.
from Crypto.Hash import [Tipo Hash]

Indicar texto para el hash.
update('texto')

Generar el hash.
Para generar el hash:
digest()

Para generar el hash en hexadecimal se usa hexdigest().

El siguiente es un ejemplo sencillo de generación de un hash:
from Crypto.Hash import MD5
m = MD5.new()
m.update('Hola mundo')
print m.digest()

A modo de ejemplo, el programa siguiente cifra un usuario y un password y, posteriormente, simulando que es el servidor que ha recibido dichas credenciales, descifra y muestra dichos datos.

from Crypto.Cipher import DES
# Como usamos DES, los bloques son de 8 caracteres.
# Rellenamos con espacios (que habra que eliminar al descifrar).
usuario =  "John    "
password = "Lennon  "
# creamos el cifrador con DES
cipher = DES.new('12345678')
# ciframos usuario y password
c_usuario = cipher.encrypt(usuario)
c_password = cipher.encrypt(password)
# enviamos credenciales (a la pantalla en este caso)
print "El cliente envia:"
print "Usuario: " + c_usuario
print "Password: " + c_password

#------------------------------------------------------------------
# a partir de aqui simulamos el servidor donde llegan los mensajes
# cifrados.
# desciframos mensajes y quitamos espacios con strip()
cipher = DES.new('12345678')
d_usuario = cipher.decrypt(c_usuario).strip()
d_password = cipher.decrypt(c_password).strip()
print "El servidor descifra:"
print "Usuario: " + d_usuario
print "Password: " + d_password

El programa cifra los datos usando DES, así que lo primero que hace es importar el módulo DES y crear un cifrador con la siguiente instrucción:
cipher = DES.new('12345678')

El parámetro '12345678' es la clave de cifrado. Como hemos visto, hay otros parámetros que en este caso se han omitido y, por lo tanto, toman valores por defecto.
Una vez creado el cifrador, como se puede ver en el programa de ejemplo, el cifrado y descifrado es bastante sencillo. Para cifrar usamos:
cipher.encrypt('texto en claro')

Y para descifrar:
cipher.decrypt('texto cifrado')

En este caso hemos usado DES, que es un cifrado por bloques, lo que nos obliga a que el texto a cifrar sea múltiplo de 8, así que he añadido espacios al final del texto. Al descifrarlo los he quitado.
Se podría haber usado un cifrador por flujo (también soportado por la librería) para evitar este inconveniente.

Comentarios

  1. gracias por la explicacion, en los ejemplo de la libreria solo venian sha265 aes y random, pense que era todo lo que tenia pycrypto

    ResponderEliminar
  2. hola, tengo una duda, si mi clave K está codificada en hexadecimal y encriptada en AES, como tendré que hacerlo para incluirla dentro de pycripto? tal cual? o tendré que hacer un tratamiento antes? si la paso por algun convertidor de hex a ascii me dice que el formato no es valido.

    Agradeceria mucho una pronta respuesta,

    ResponderEliminar
  3. Hola Alberto,
    He seguido tu pasos pero no consigo descifrar con ARC4.
    Este seria el codigo que estoy utilizando:
    from Crypto.Cipher import ARC4

    claveHex = 'A13F06C89B1E3B56789F' #La semilla usada para generar la clave es de 80 bits (10 bytes).
    clave = claveHex.encode()
    print (clave) # b'A13F06C89B1E3B56789F'

    #texto = Este es un simple texto de prueba para ser cifrado
    texto = '4573746520657320756E2073696D706C6520746578746F20646520707275656261207061726120736572206369667261646F'

    print (texto.encode()) # b'4573746520657320756E2073696D706C6520746578746F20646520707275656261207061726120736572206369667261646F'


    cif = ARC4.new(clave)

    text_cifrado = cif.encrypt(texto.encode())
    text_descifrado = cif.decrypt(text_cifrado)

    print (text_descifrado)
    #b'l\xd7\xa4\xa1\xcbA\x17\xa2zg1\xaa\xb4\x00\x17\xc6o\xfa\xda\xa9\x01\xe6\x97\n\x1fI\x95==1^\x97N\xfbT\xcc\x9b4\xf7w\x8d{\x9d\xb6hZl\x91\xc0\x82\x1e\xbe\x15\xf8\xde7Fpi\xc9\r\xd4wN\xa8\xbe\x93\xad4\xad\xf9\xc2X\xbdb\xe2\xf2\x80\xf0\xdb4/Iwy\x9e\xb0\x81?\x85\x0b\x91\x0bc\x05\x8e\x02\x80\x8eM'

    ¿Se te ocurre que puede estar mal?

    ResponderEliminar
  4. Hola Alberto,
    He seguido tus pasos pero no se que puede estar mal.
    Te adjunto el codigo por si me puedes echar una mano.

    ************************************
    from Crypto.Cipher import ARC4

    claveHex = 'A13F06C89B1E3B56789F' #La semilla usada para generar la clave es de 80 bits (10 bytes).
    clave = claveHex.encode()
    print (clave) # b'A13F06C89B1E3B56789F'

    #texto = Este es un simple texto de prueba para ser cifrado
    texto = '4573746520657320756E2073696D706C6520746578746F20646520707275656261207061726120736572206369667261646F'

    print (texto.encode()) # b'4573746520657320756E2073696D706C6520746578746F20646520707275656261207061726120736572206369667261646F'


    cif = ARC4.new(clave)

    text_cifrado = cif.encrypt(texto.encode())
    text_descifrado = cif.decrypt(text_cifrado)

    print (text_descifrado)
    #b'l\xd7\xa4\xa1\xcbA\x17\xa2zg1\xaa\xb4\x00\x17\xc6o\xfa\xda\xa9\x01\xe6\x97\n\x1fI\x95==1^\x97N\xfbT\xcc\x9b4\xf7w\x8d{\x9d\xb6hZl\x91\xc0\x82\x1e\xbe\x15\xf8\xde7Fpi\xc9\r\xd4wN\xa8\xbe\x93\xad4\xad\xf9\xc2X\xbdb\xe2\xf2\x80\xf0\xdb4/Iwy\x9e\xb0\x81?\x85\x0b\x91\x0bc\x05\x8e\x02\x80\x8eM'

    Saludos


    ResponderEliminar
  5. instala la libreria pycrypto en un macOS y su uso...

    ResponderEliminar

Publicar un comentario

Entradas populares de este blog

Creando firmas de virus para ClamAV

ClamAv es un antivirus opensource y multiplataforma creado por Tomasz Kojm muy utilizado en los servidores de correo Linux. Este antivirus es desarrollado por la comunidad, y su utilidad práctica depende de que su base de datos de firmas sea lo suficientemente grande y actualizado. Para ello es necesario que voluntarios contribuyan activamente aportando firmas. El presente artículo pretende describir de manera sencilla cómo crear firmas de virus para ClamAV y contribuir con ellas a la comunidad.

Manejo de grafos con NetworkX en Python

El aprendizaje computacional es un área de investigación que en los últimos años ha tenido un auge importante, sobre todo gracias al aprendizaje profundo (Deep Learning). Pero no todo son redes neuronales. Paralelamente a estas técnicas, más bien basadas en el aprendizaje de patrones, también hay un auge de otras técnicas, digamos, más basadas en el aprendizaje simbólico. Si echamos la vista algunos años atrás, podemos considerar que quizá, la promesa de la web semántica como gran base de conocimiento ha fracasado, pero no es tan así. Ha ido transmutándose y evolucionando hacia bases de conocimiento basadas en ontologías a partir de las cuales es posible obtener nuevo conocimiento. Es lo que llamamos razonamiento automático y empresas como Google ya lo utilizan para ofrecerte información adicional sobre tus búsquedas. Ellos lo llaman Grafos de Conocimiento o Knowledge Graphs . Gracias a estos grafos de conocimiento, Google puede ofrecerte información adicional sobre tu búsqueda, ad

Scripts en NMAP

Cuando pensamos en NMAP, pensamos en el escaneo de puertos de un host objetivo al que estamos relizando una prueba de intrusión, pero gracias a las posibilidades que nos ofrecen su Scripting Engine , NMAP es mucho más que eso. Antes de continuar, un aviso: algunas de posibilidades que nos ofrecen los scripts de NMAP son bastante intrusivas, por lo que recomiendo hacerlas contra hosts propios, máquinas virtuales como las de Metasploitable, o contrato de pentesting mediante. Para este artículo voy a usar las máquinas de Metasploitable3 . No voy a entrar en los detalles sobre el uso básico de NMAP, ya que hay miles de tutoriales en Internet que hablan sobre ello. Lo cierto es que NMAP tiene algunas opciones que permiten obtener información extra, además de qué puertos están abiertos y cuales no. Por ejemplo, la opción -sV trata de obtener el servicio concreto, e incluso la versión del servicio que está corriendo en cada puerto. Otro ejemplo es la opción -O, que intenta averiguar el