Implementing End-to-End Encryption Using PyCryptodome

Implementing End-to-End Encryption Using PyCryptodome

In today’s digital landscape, ensuring data security is crucial. End-to-End Encryption (E2EE) guarantees that only the sender and recipient can view the original message, effectively blocking any third parties, including service providers, from eavesdropping. In this blog, we will implement E2EE using PyCryptodome, a powerful cryptographic library in Python.

We’ll guide you through each step:

Key generation

– Encryption

– Secure transmission

– Decryption

By the end, you’ll have a functional encryption system for secure communication.

1. Install PyCryptodome

Before we start, make sure to install PyCryptodome using pip:

pip install pycryptodome

2. Generate RSA Key Pair

We will use RSA (Rivest-Shamir-Adleman) for asymmetric encryption, where a public key encrypts the data and a private key decrypts it.

from Crypto.PublicKey import RSA

def generate_rsa_keys():
    key = RSA.generate(2048)  # Generate a 2048-bit RSA key pair
    private_key = key.export_key()
    public_key = key.publickey().export_key()
    
    with open("private.pem", "wb") as priv_file:
        priv_file.write(private_key)
        
    with open("public.pem", "wb") as pub_file:
        pub_file.write(public_key)
    
    print("Keys generated and saved successfully.")

generate_rsa_keys()

3. Encrypt Data Using the Public Key

The sender encrypts the message with the recipient’s public key.

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

def encrypt_message(message, public_key_file="public.pem"):
    with open(public_key_file, "rb") as pub_file:
        public_key = RSA.import_key(pub_file.read())
    
    cipher = PKCS1_OAEP.new(public_key)  # Create cipher object
    encrypted_message = cipher.encrypt(message.encode())  # Encrypt message
    
    return base64.b64encode(encrypted_message).decode()  # Convert to base64 for safe transmission

message = "Hello, this is a secret message!"
encrypted_msg = encrypt_message(message)
print("Encrypted Message:", encrypted_msg)

4. Securely Transmit the Encrypted Message

At this stage, the sender can send the base64-encoded encrypted message via email, chat, or any communication channel.

5. Decrypt Data Using the Private Key

The recipient decrypts the message using their private key.

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

def decrypt_message(encrypted_message, private_key_file="private.pem"):
    with open(private_key_file, "rb") as priv_file:
        private_key = RSA.import_key(priv_file.read())

    cipher = PKCS1_OAEP.new(private_key)  # Create cipher object
    decoded_encrypted_message = base64.b64decode(encrypted_message)  # Decode from base64
    decrypted_message = cipher.decrypt(decoded_encrypted_message)  # Decrypt message

    return decrypted_message.decode()

decrypted_msg = decrypt_message(encrypted_msg)
print("Decrypted Message:", decrypted_msg)

6. Adding AES for Symmetric Encryption

RSA is not ideal for encrypting large files. Instead, we use AES (Advanced Encryption Standard) for encrypting bulk data and RSA for securely sharing the AES key.

Generate a Random AES Key

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

def generate_aes_key():
    key = get_random_bytes(32)  # 256-bit key
    with open("aes_key.bin", "wb") as key_file:
        key_file.write(key)
    
    return key

aes_key = generate_aes_key()
print("AES Key Generated:", aes_key)

Encrypt a File Using AES

from Crypto.Cipher import AES
from Crypto.Util.Padding import pad

def encrypt_file(file_path, key):
    cipher = AES.new(key, AES.MODE_CBC)  # Initialize AES cipher in CBC mode
    with open(file_path, "rb") as file:
        plaintext = file.read()
    
    ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))  # Encrypt and pad
    with open(file_path + ".enc", "wb") as enc_file:
        enc_file.write(cipher.iv + ciphertext)  # Store IV + Ciphertext

    print("File encrypted successfully.")

encrypt_file("sample.txt", aes_key)

Decrypt a File Using AES

from Crypto.Util.Padding import unpad

def decrypt_file(file_path, key):
    with open(file_path, "rb") as enc_file:
        iv = enc_file.read(16)  # Extract IV
        ciphertext = enc_file.read()

    cipher = AES.new(key, AES.MODE_CBC, iv)  # Initialize AES cipher with IV
    decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)  # Decrypt and remove padding

    with open(file_path.replace(".enc", "_decrypted.txt"), "wb") as dec_file:
        dec_file.write(decrypted_data)

    print("File decrypted successfully.")

decrypt_file("sample.txt.enc", aes_key)

7. Securely Share the AES Key Using RSA

The sender encrypts the AES key with the recipient’s public RSA key.

def encrypt_aes_key(aes_key, public_key_file="public.pem"):
    with open(public_key_file, "rb") as pub_file:
        public_key = RSA.import_key(pub_file.read())

    cipher = PKCS1_OAEP.new(public_key)
    encrypted_key = cipher.encrypt(aes_key)

    return base64.b64encode(encrypted_key).decode()

encrypted_aes_key = encrypt_aes_key(aes_key)
print("Encrypted AES Key:", encrypted_aes_key)

The recipient decrypts the AES key with their private RSA key.

def decrypt_aes_key(encrypted_key, private_key_file="private.pem"):
    with open(private_key_file, "rb") as priv_file:
        private_key = RSA.import_key(priv_file.read())

    cipher = PKCS1_OAEP.new(private_key)
    decrypted_key = cipher.decrypt(base64.b64decode(encrypted_key))

    return decrypted_key

decrypted_aes_key = decrypt_aes_key(encrypted_aes_key)
print("Decrypted AES Key:", decrypted_aes_key)

Conclusion

we have successfully developed an effective end-to-end encryption system in our solution with the following attributes: A key exchange with RSA; encryption of messages and files using AES; messages and keys are then securely transmitted. The methodology guarantees utmost confidentiality and security of data.

Leave a Comment

Your email address will not be published. Required fields are marked *

Scroll to Top