Saltar al pie de página
AYUDA DE PYTHON

Usando PyCryptodome para Encriptación en Python

En la era de la transformación digital, la importancia de los mecanismos criptográficos robustos no puede ser exagerada. La criptografía asegura la seguridad y privacidad de los datos mientras atraviesan diversas redes y sistemas. PyCryptodome es una biblioteca de Python que destaca en el panorama criptográfico, ofreciendo una multitud de funcionalidades para facilitar el manejo seguro de datos, como modos de cifrado autenticados (GCM, CCM, EAX, SIV, OCB) y AES acelerado con soporte de primera clase. Este artículo profundiza en la última versión oficial de PyCryptodome, explorando sus características, casos de uso, proceso de instalación simplificado y cómo puede utilizarse eficazmente en varias aplicaciones. También crearemos archivos PDF cifrados usando una biblioteca separada de C#, IronPDF, con PyCryptodome.

Descripción general de PyCryptodome

PyCryptodome es un paquete de Python independiente de primitivas criptográficas de bajo nivel. Se diseñó para ser un reemplazo directo de la antigua biblioteca PyCrypto, abordando muchas de sus limitaciones y ampliando sus capacidades. Proporciona una amplia gama de algoritmos y protocolos criptográficos, convirtiéndolo en una herramienta invaluable para desarrolladores que necesitan implementar características de seguridad en sus aplicaciones.

Características clave

  1. Amplio Soporte de Algoritmos: PyCryptodome soporta una gama completa de algoritmos criptográficos, incluyendo AES, RSA, DSA y muchos más. Este extenso soporte asegura que los desarrolladores puedan encontrar las herramientas necesarias para diversas necesidades criptográficas.
  2. Facilidad de Uso: La biblioteca está diseñada para ser fácil de usar, con una API clara y concisa que permite incluso a aquellos con conocimiento criptográfico limitado implementar características de seguridad de manera efectiva.
  3. Mantenimiento Activo: A diferencia de su predecesora PyCrypto, PyCryptodome se mantiene activamente, con actualizaciones regulares y mejoras, asegurando compatibilidad con las últimas versiones de Python y estándares de seguridad.
  4. Independiente: PyCryptodome no requiere ninguna dependencia externa, haciéndolo fácil de instalar y usar en diferentes entornos.
  5. Integración con Bibliotecas Existentes: PyCryptodome puede integrarse sin problemas con otras bibliotecas y frameworks de Python, mejorando su utilidad en varias aplicaciones.

Instalación

Instalar PyCryptodome es un proceso simple, gracias a su naturaleza independiente. Se puede instalar mediante pip, el instalador de paquetes de Python, usando el siguiente comando:

pip install pycryptodome
pip install pycryptodome
SHELL

Conceptos básicos y módulos

PyCryptodome está organizado en varios módulos, cada uno atendiendo diferentes aspectos de la criptografía. Entender estos módulos es crucial para aprovechar eficazmente la biblioteca.

Hashing

Las funciones hash son fundamentales para la criptografía, proporcionando una forma de producir un valor hash de tamaño fijo a partir de datos arbitrarios. PyCryptodome soporta varios algoritmos hash a través del módulo Crypto.Hash.

Ejemplo de uso de la función hash SHA-256

from Crypto.Hash import SHA256

# Create a new SHA-256 hash object
hash_object = SHA256.new(data=b'Hello, PyCryptodome!')

# Output the hexadecimal digest of the hash
print(hash_object.hexdigest())
from Crypto.Hash import SHA256

# Create a new SHA-256 hash object
hash_object = SHA256.new(data=b'Hello, PyCryptodome!')

# Output the hexadecimal digest of the hash
print(hash_object.hexdigest())
PYTHON

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 1 - Salida Hash

Encriptación simétrica

El cifrado simétrico utiliza la misma clave tanto para el cifrado como para el descifrado. El módulo Crypto.Cipher de PyCryptodome soporta varios cifrados simétricos, incluyendo AES, DES y más.

Ejemplo de cifrado y descifrado AES

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

# Generate a random AES key
key = get_random_bytes(16)  # 16 bytes for AES-128

# Create a new AES cipher in EAX mode for encryption
cipher = AES.new(key, AES.MODE_EAX)
data = b'Secret Message'

# Encrypt the data and get the nonce, ciphertext and tag
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(data)

# Create a new AES cipher in EAX mode for decryption
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)

# Verify the authenticity of the message
try:
    cipher.verify(tag)
    print("The message is authentic:", plaintext)
except ValueError:
    print("Key incorrect or message corrupted")
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes

# Generate a random AES key
key = get_random_bytes(16)  # 16 bytes for AES-128

# Create a new AES cipher in EAX mode for encryption
cipher = AES.new(key, AES.MODE_EAX)
data = b'Secret Message'

# Encrypt the data and get the nonce, ciphertext and tag
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(data)

# Create a new AES cipher in EAX mode for decryption
cipher = AES.new(key, AES.MODE_EAX, nonce=nonce)
plaintext = cipher.decrypt(ciphertext)

# Verify the authenticity of the message
try:
    cipher.verify(tag)
    print("The message is authentic:", plaintext)
except ValueError:
    print("Key incorrect or message corrupted")
PYTHON

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 2 - Salida AES

Encriptación asimétrica

El cifrado asimétrico utiliza un par de claves: una clave pública para cifrar y una clave privada para descifrar. El módulo Crypto.PublicKey de PyCryptodome proporciona soporte para RSA, DSA y ECC (Criptografía de Curva Elíptica).

Ejemplo de cifrado y descifrado RSA

from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

# Generate an RSA key pair
key = RSA.generate(2048)
public_key = key.publickey()

# Encrypt the message using the public key
cipher = PKCS1_OAEP.new(public_key)
ciphertext = cipher.encrypt(b'Secret Message')

# Decrypt the message using the private key
cipher = PKCS1_OAEP.new(key)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
from Crypto.PublicKey import RSA
from Crypto.Cipher import PKCS1_OAEP

# Generate an RSA key pair
key = RSA.generate(2048)
public_key = key.publickey()

# Encrypt the message using the public key
cipher = PKCS1_OAEP.new(public_key)
ciphertext = cipher.encrypt(b'Secret Message')

# Decrypt the message using the private key
cipher = PKCS1_OAEP.new(key)
plaintext = cipher.decrypt(ciphertext)
print(plaintext)
PYTHON

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 3 - Salida RSA

Derivación clave

Las funciones de derivación de claves generan claves criptográficas a partir de una contraseña o frase de paso. Esto es particularmente útil en el cifrado basado en contraseñas. PyCryptodome soporta PBKDF2, scrypt y otros algoritmos de derivación de claves.

Ejemplo de uso de PBKDF2

from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes

# Define a password and generate a salt
password = b'my secret password'
salt = get_random_bytes(16)

# Derive a key from the password and salt using PBKDF2
key = PBKDF2(password, salt, dkLen=32, count=1000000)
print(key)
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes

# Define a password and generate a salt
password = b'my secret password'
salt = get_random_bytes(16)

# Derive a key from the password and salt using PBKDF2
key = PBKDF2(password, salt, dkLen=32, count=1000000)
print(key)
PYTHON

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 4 - Salida PBKDF2

Casos prácticos

Gestión de contraseñas

Los gestores de contraseñas se benefician de las funciones de derivación de claves de PyCryptodome para almacenar y recuperar de manera segura las contraseñas de los usuarios. Al usar fuertes algoritmos de derivación de claves como PBKDF2, los desarrolladores pueden asegurar que las contraseñas almacenadas sean resistentes a ataques de fuerza bruta.

Ejemplo de seguridad de contraseñas

from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES

# Derive a strong key from a password
password = b'user_password'
salt = get_random_bytes(16)
key = PBKDF2(password, salt, dkLen=32, count=1000000)

# Encrypt the password before storing
cipher = AES.new(key, AES.MODE_EAX)
stored_password = b'ActualPassword'
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(stored_password)

# Store ciphertext, nonce, salt, and tag securely
password_data = {
    'ciphertext': ciphertext,
    'nonce': nonce,
    'salt': salt,
    'tag': tag
}

# Decrypt the password when needed
key = PBKDF2(password, password_data['salt'], dkLen=32, count=1000000)
cipher = AES.new(key, AES.MODE_EAX, nonce=password_data['nonce'])
plaintext = cipher.decrypt(password_data['ciphertext'])

# Verify the authenticity of the password
try:
    cipher.verify(password_data['tag'])
    print("The stored password is authentic:", plaintext)
except ValueError:
    print("Key incorrect or password corrupted")
from Crypto.Protocol.KDF import PBKDF2
from Crypto.Random import get_random_bytes
from Crypto.Cipher import AES

# Derive a strong key from a password
password = b'user_password'
salt = get_random_bytes(16)
key = PBKDF2(password, salt, dkLen=32, count=1000000)

# Encrypt the password before storing
cipher = AES.new(key, AES.MODE_EAX)
stored_password = b'ActualPassword'
nonce = cipher.nonce
ciphertext, tag = cipher.encrypt_and_digest(stored_password)

# Store ciphertext, nonce, salt, and tag securely
password_data = {
    'ciphertext': ciphertext,
    'nonce': nonce,
    'salt': salt,
    'tag': tag
}

# Decrypt the password when needed
key = PBKDF2(password, password_data['salt'], dkLen=32, count=1000000)
cipher = AES.new(key, AES.MODE_EAX, nonce=password_data['nonce'])
plaintext = cipher.decrypt(password_data['ciphertext'])

# Verify the authenticity of the password
try:
    cipher.verify(password_data['tag'])
    print("The stored password is authentic:", plaintext)
except ValueError:
    print("Key incorrect or password corrupted")
PYTHON

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 5 - Salida de Aseguramiento de Contraseñas

IronPDF for Python

IronPDF es una potente biblioteca de generación de PDF para Python que permite a los desarrolladores crear, editar y manipular documentos PDF sin esfuerzo. Proporciona una amplia gama de funcionalidades, desde convertir HTML a PDF hasta fusionar múltiples PDFs, siendo una elección ideal para automatizar flujos de trabajo de documentos. Cuando se combina con PyCryptodome, una robusta biblioteca para operaciones criptográficas, los desarrolladores pueden agregar características de seguridad a sus documentos PDF, como cifrado y firmas digitales. Esta integración es particularmente útil para aplicaciones que requieren altos niveles de seguridad e integridad de datos, como en entornos financieros, legales o confidenciales.

Para instalar IronPDF, puedes usar pip, el gestor de paquetes de Python. Aquí está cómo comenzar:

pip install ironpdf
pip install ironpdf
SHELL

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 6 - IronPDF

Después de la instalación, puedes comenzar a usar IronPDF para crear y manipular PDFs. A continuación se muestra un ejemplo simple que demuestra cómo crear un PDF con IronPDF y luego usar PyCryptodome para cifrarlo:

from ironpdf import ChromePdfRenderer
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import os

# Create a new PDF renderer
renderer = ChromePdfRenderer()

# Render a URL as a PDF and save it
pdfFromUrl = renderer.RenderUrlAsPdf("https://ironpdf.com/")
pdfFromUrl.SaveAs("output.pdf")

# Function to encrypt a file using AES
def encrypt_file(file_name, key):
    cipher = AES.new(key, AES.MODE_CBC)  # Use AES in CBC mode
    iv = cipher.iv
    with open(file_name, 'rb') as f:
        data = f.read()
    encrypted_data = iv + cipher.encrypt(pad(data, AES.block_size))
    with open(file_name + '.enc', 'wb') as f:
        f.write(encrypted_data)

# Example usage
key = os.urandom(16)  # AES key must be either 16, 24, or 32 bytes long
encrypt_file("output.pdf", key)
from ironpdf import ChromePdfRenderer
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad
import os

# Create a new PDF renderer
renderer = ChromePdfRenderer()

# Render a URL as a PDF and save it
pdfFromUrl = renderer.RenderUrlAsPdf("https://ironpdf.com/")
pdfFromUrl.SaveAs("output.pdf")

# Function to encrypt a file using AES
def encrypt_file(file_name, key):
    cipher = AES.new(key, AES.MODE_CBC)  # Use AES in CBC mode
    iv = cipher.iv
    with open(file_name, 'rb') as f:
        data = f.read()
    encrypted_data = iv + cipher.encrypt(pad(data, AES.block_size))
    with open(file_name + '.enc', 'wb') as f:
        f.write(encrypted_data)

# Example usage
key = os.urandom(16)  # AES key must be either 16, 24, or 32 bytes long
encrypt_file("output.pdf", key)
PYTHON

Este script muestra la creación de un PDF simple usando IronPDF y luego lo cifra usando AES de PyCryptodome, proporcionando una base para construir aplicaciones de manejo de PDF más complejas y seguras.

¡PyCryptodome (Cómo Funciona para Desarrolladores): Figura 7 - Salida de Archivo Cifrado

Conclusión

En conclusión, PyCryptodome es una biblioteca para Python poderosa y versátil que mejora significativamente las operaciones criptográficas para los desarrolladores, ofreciendo una amplia variedad de algoritmos y fácil integración con otras herramientas como IronPDF. Con su conjunto completo de características, incluyendo soporte para modos de cifrado autenticados, cifrado simétrico y asimétrico, hashing y derivación de claves, PyCryptodome responde a las necesidades de las aplicaciones modernas que requieren medidas de seguridad robustas. Su facilidad de uso, mantenimiento activo y naturaleza independiente lo convierten en una herramienta indispensable para implementar un manejo seguro de datos en varios escenarios, desde la gestión de contraseñas hasta la generación segura de documentos y el cifrado, asegurando la integridad y confidencialidad de los datos en un mundo cada vez más digital.

Para detalles sobre las licencias de IronPDF, consulta la página de licencia de IronPDF. Para explorar más, echa un vistazo a nuestro completo tutorial sobre la conversión de HTML a PDF.

Curtis Chau
Escritor Técnico

Curtis Chau tiene una licenciatura en Ciencias de la Computación (Carleton University) y se especializa en el desarrollo front-end con experiencia en Node.js, TypeScript, JavaScript y React. Apasionado por crear interfaces de usuario intuitivas y estéticamente agradables, disfruta trabajando con frameworks modernos y creando manuales bien ...

Leer más