Symmetric Encryption

Basics of Symmetric Encryption

Symmetric encryption is a type of encryption where the same key is used to both encrypt and decrypt the data. This key must be shared between the sender and receiver, making it important to ensure the key is distributed securely. Symmetric encryption is widely used because of its speed and efficiency, especially when encrypting large amounts of data.

Key Characteristics:

  • Single key: One shared key is used for both encryption and decryption.

  • Fast and efficient: Ideal for encrypting large datasets.

  • Key distribution challenge: Both parties must securely exchange the secret key.


Block Ciphers vs. Stream Ciphers

Symmetric encryption algorithms can be broadly categorized into two types: block ciphers and stream ciphers.

Block Ciphers

Block ciphers work by dividing the plaintext into fixed-size blocks (e.g., 128-bit blocks), then encrypting each block individually using the encryption key. If the data is not a multiple of the block size, padding is added to the final block.

Popular block ciphers:

  • AES (Advanced Encryption Standard)

  • DES (Data Encryption Standard)

Stream Ciphers

Stream ciphers encrypt plaintext one bit or byte at a time by combining it with a key stream. The key stream is generated from the encryption key, and each bit/byte of plaintext is XORed with the corresponding bit/byte of the key stream to produce the ciphertext.

Popular stream ciphers:

  • RC4

  • ChaCha20


Implementation of AES Encryption in Python

AES (Advanced Encryption Standard) is one of the most widely used symmetric encryption algorithms. It operates on fixed-size blocks of 128 bits and supports key sizes of 128, 192, or 256 bits. AES can operate in several modes, including CBC (Cipher Block Chaining), ECB (Electronic Codebook), and CTR (Counter).

In this tutorial, we'll focus on AES in CBC mode, which is widely used due to its added security compared to ECB mode. In CBC mode, each block of plaintext is XORed with the previous ciphertext block before being encrypted, and the first block is XORed with an Initialization Vector (IV).


Interactive Example: Encrypting and Decrypting Data Using AES in CBC Mode

We'll use the pycryptodome library to implement AES encryption and decryption in Python. If you haven't installed it yet, you can install it using:

pip install pycryptodome

Example: AES Encryption in CBC Mode

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad

# Define the encryption key (16, 24, or 32 bytes for AES-128, AES-192, or AES-256)
key = get_random_bytes(16)  # 16 bytes = 128 bits

# Define the plaintext
plaintext = b"This is a secret message"

# Generate a random IV (Initialization Vector) for CBC mode
iv = get_random_bytes(16)  # 16 bytes = 128 bits

# Create a new AES cipher object in CBC mode
cipher = AES.new(key, AES.MODE_CBC, iv)

# Pad the plaintext to ensure it's a multiple of the block size (16 bytes for AES)
padded_plaintext = pad(plaintext, AES.block_size)

# Encrypt the padded plaintext
ciphertext = cipher.encrypt(padded_plaintext)

print(f"Ciphertext: {ciphertext.hex()}")

Explanation:

1. We generate a random encryption key using get_random_bytes(). This key must be kept secret.

2. The plaintext message is defined as a byte string.

3. A random IV is generated to ensure that the same plaintext encrypted multiple times will produce different ciphertexts.

4. The pad() function ensures that the plaintext is padded to a multiple of AES’s block size (16 bytes).

5. The ciphertext is generated by encrypting the padded plaintext using AES in CBC mode.

Example: AES Decryption in CBC Mode

# Create a new AES cipher object for decryption in CBC mode
decipher = AES.new(key, AES.MODE_CBC, iv)

# Decrypt the ciphertext
decrypted_padded_plaintext = decipher.decrypt(ciphertext)

# Unpad the decrypted plaintext
decrypted_plaintext = unpad(decrypted_padded_plaintext, AES.block_size)

print(f"Decrypted Plaintext: {decrypted_plaintext.decode()}")

Explanation:

1. A new AES cipher object is created for decryption, using the same key and IV as for encryption.

2. The ciphertext is decrypted to produce the padded plaintext.

3. The unpad() function removes the padding added during encryption to restore the original plaintext.

Complete Example: Encryption and Decryption with AES in CBC Mode

from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
from Crypto.Util.Padding import pad, unpad

# Define the encryption key
key = get_random_bytes(16)  # 16 bytes = 128 bits

# Define the plaintext
plaintext = b"This is a secret message"

# Generate a random IV
iv = get_random_bytes(16)

# Create an AES cipher object for encryption (CBC mode)
cipher = AES.new(key, AES.MODE_CBC, iv)

# Pad the plaintext and encrypt
padded_plaintext = pad(plaintext, AES.block_size)
ciphertext = cipher.encrypt(padded_plaintext)

print(f"Ciphertext: {ciphertext.hex()}")

# Create an AES cipher object for decryption (CBC mode)
decipher = AES.new(key, AES.MODE_CBC, iv)

# Decrypt the ciphertext and unpad
decrypted_padded_plaintext = decipher.decrypt(ciphertext)
decrypted_plaintext = unpad(decrypted_padded_plaintext, AES.block_size)

print(f"Decrypted Plaintext: {decrypted_plaintext.decode()}")

This complete example shows the entire process of encrypting and decrypting data using AES in CBC mode. The encryption process includes padding the plaintext to match the block size and using a random IV to enhance security. The decryption process removes the padding and restores the original plaintext.

Symmetric encryption, especially with AES, is a foundational tool in securing sensitive data. While it is fast and efficient, symmetric encryption has its challenges, particularly in securely sharing the encryption key between parties. Understanding the basics of block ciphers like AES and their implementation in CBC mode helps in building secure systems for real-world applications.

Last updated