Featured

Symmetric Encryption in Python with PyCrypto: AES Encryption Example

Symmetric Encryption in Python with PyCrypto: AES Encryption Example

Dharambir
Dharambir
12 January 2025 min read
ProgrammingPythonSoftware DevelopmentCoding TutorialsProgramming TutorialsSecurity & Encryption

Encryption is a critical part of securing data, especially in the age of cyber threats and privacy concerns. If you're working on a Python project that requires encrypting sensitive information, symmetric encryption is a popular approach. One of the most robust encryption algorithms in use today is AES (Advanced Encryption Standard), and it can be implemented in Python using the PyCrypto library (now maintained under the name pycryptodome).

In this article, we’ll dive into how to use AES for symmetric encryption in Python, specifically using a passphrase to derive encryption keys and initialization vectors (IVs). We’ll go through both the encryption and decryption process, and also explain the underlying mechanisms for secure encryption practices.

What is Symmetric Encryption?

Symmetric encryption refers to encryption algorithms where the same key is used for both encryption and decryption. The key must be kept secret, and whoever has the key can decrypt the information.

AES Algorithm

AES is a widely used symmetric encryption algorithm that offers a strong level of security. It supports key sizes of 128, 192, and 256 bits. AES-256 is the most secure version, and we will use this for our encryption.

Why Use a Passphrase?

In real-world applications, it's often impractical to use a completely random key for encryption because it’s not easy to remember or store. Therefore, we use a passphrase (something the user can remember, like a password) to derive the key for AES encryption. The passphrase needs to be processed into an appropriate format (key and IV) using a cryptographic function like PBKDF2.

The challenge is that a passphrase doesn’t have enough entropy (randomness) to be used directly as a key. This is where key derivation functions (KDFs) come into play to securely generate the key and initialization vector (IV).

How to Encrypt and Decrypt with AES in Python

Let's break down the encryption and decryption steps using the PyCryptodome library (a fork of the original PyCrypto library), focusing on using a passphrase for AES encryption.

Step 1: Installing PyCryptodome

To get started, you need to install the pycryptodome package, which provides AES functionality. You can install it using pip:

pip install pycryptodome

Step 2: Encrypting a Message Using AES

Here’s a step-by-step explanation of how to encrypt a message using a passphrase:

import hashlib
import os
from Crypto.Cipher import AES
 
# Constants for AES encryption
IV_SIZE = 16  # 128 bit, fixed for AES
KEY_SIZE = 32  # 256 bit key for AES-256
SALT_SIZE = 16  # Salt size (can be arbitrary, here it's 16 bytes)
 
# Cleartext message to encrypt
cleartext = b'Lorem ipsum'
 
# User-defined password (passphrase)
password = b'highly secure encryption password'
 
# Generate a random salt
salt = os.urandom(SALT_SIZE)
 
# Derive key and IV from the password using PBKDF2
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000, dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE]  # First 16 bytes as IV
key = derived[IV_SIZE:]  # Next 32 bytes as key
 
# Encrypt the message using AES in CFB mode
cipher = AES.new(key, AES.MODE_CFB, iv)
encrypted = salt + cipher.encrypt(cleartext)
 
# Output the encrypted message
print("Encrypted message:", encrypted)

Key Components of the Code:

  • PBKDF2: We use the hashlib.pbkdf2_hmac function to generate the key and IV from the passphrase. The result is 48 bytes: the first 16 bytes are the IV, and the next 32 bytes are the encryption key.
  • Salt: A randomly generated salt is prepended to the encrypted message. The salt ensures that even if the same message is encrypted with the same passphrase, the result will be different each time.
  • AES: We use the AES algorithm in CFB mode (Cipher Feedback Mode), which is a secure way to encrypt data where the encryption is performed on smaller blocks, offering better security.

Step 3: Decrypting the Message

Now let’s look at how to decrypt the encrypted message back into its original form.

# Extract the salt from the encrypted message
salt = encrypted[0:SALT_SIZE]
 
# Derive the key and IV from the password using the extracted salt
derived = hashlib.pbkdf2_hmac('sha256', password, salt, 100000, dklen=IV_SIZE + KEY_SIZE)
iv = derived[0:IV_SIZE]  # First 16 bytes as IV
key = derived[IV_SIZE:]  # Next 32 bytes as key
 
# Decrypt the message using AES in CFB mode
cipher = AES.new(key, AES.MODE_CFB, iv)
cleartext = cipher.decrypt(encrypted[SALT_SIZE:])
 
# Output the decrypted message
print("Decrypted message:", cleartext.decode())

Explanation:

  • Extract Salt: The salt is the first part of the encrypted message. We extract it from the beginning to rederive the key and IV.
  • Key and IV Derivation: We use the same pbkdf2_hmac function to regenerate the key and IV using the password and salt.
  • Decryption: The encrypted message is decrypted using the same AES key and IV in CFB mode.

Step 4: Handling Padding (Optional)

In some AES modes (like CBC), you’ll need to pad your plaintext to ensure that its length is a multiple of the block size. However, since we’re using CFB mode, the data can be of any length, so no padding is necessary.

Security Considerations

  1. Strong Passphrase: The security of your encryption relies heavily on the strength of the passphrase. Use a long, complex passphrase to ensure better security.
  2. Salt: Always use a random salt for each encryption operation. The salt must be stored alongside the encrypted message to enable proper decryption.
  3. Secure Key Management: While we use a passphrase to generate the key, in real-world scenarios, securely storing and managing keys is vital to protect sensitive data.

Conclusion

In this article, we covered how to use the AES algorithm for symmetric encryption in Python with the pycryptodome library. We demonstrated how to securely derive the encryption key and IV from a user-provided passphrase, encrypt data, and decrypt it back to its original form. This technique ensures that sensitive information is protected, and it highlights the importance of using strong, cryptographically secure practices like salt and key derivation functions (PBKDF2) for encryption.

By implementing AES in your Python projects, you can add a layer of security to your applications and ensure that your sensitive data remains confidential.

#AES Encryption#Python Cryptography#PyCrypto Tutorial#Secure Data Transmission#Password Encryption#Cryptography Libraries
Share:
Dharambir

Dharambir