Practical 4
1.ECB
1. ECB (Electronic Codebook)
How it works
The plaintext is divided into 8-byte blocks.
Each block is encrypted independently using the same key.
Diagram
Plaintext:
P1   P2   P3
 |    |    |
DES  DES  DES
 |    |    |
 C1   C2   C3
Formula
Ci = E(K, Pi)
where:
Pi = Plaintext block
Ci = Ciphertext block
K = Secret key
Advantages
Simple to implement.
Fast because blocks can be encrypted independently.
Disadvantages
Identical plaintext blocks produce identical ciphertext blocks.
Reveals patterns in the data.
Least secure mode.
Padding
Required
Code:-
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
import base64
def pad(text):
    while len(text) % 8 != 0:
        text += " "
    return text
def generate_des_key():
    return get_random_bytes(8)
def encrypt_des(plain_text, key):
    des = DES.new(key, DES.MODE_ECB)
    padded_text = pad(plain_text)
    encrypted_text = des.encrypt(padded_text.encode("utf-8"))
    return base64.b64encode(encrypted_text).decode("utf-8")
def decrypt_des(cipher_text, key):
    des = DES.new(key, DES.MODE_ECB)
    decrypted_text = des.decrypt(base64.b64decode(cipher_text))
    return decrypted_text.decode("utf-8").rstrip()
if __name__ == "__main__":
    key = generate_des_key()
    print(f"DES Key (Base64): {base64.b64encode(key).decode()}")
    message = "Hello DES!"
    print("Original Message:", message)
    encrypted = encrypt_des(message, key)
    print("Encrypted (Base64):", encrypted)
    decrypted = decrypt_des(encrypted, key)
    print("Decrypted Message:", decrypted)
Output:-
2. CBC (Cipher Block Chaining)
How it works
Before encrypting each block, it is XORed with the previous ciphertext block.
For the first block, an Initialization Vector (IV) is used.
Diagram
     IV
       |
P1 --->⊕----> DES ----> C1
              ^
              |
P2 --->⊕------|
              |
             C1
P3 --->⊕------|
              |
             C2
Formula
First block
C1 = E(K, P1 ⊕ IV)
Remaining blocks
Ci = E(K, Pi ⊕ Ci-1)
Advantages
Same plaintext blocks produce different ciphertext.
Much more secure than ECB.
Disadvantages
Encryption cannot be parallelized easily.
If one ciphertext block is corrupted, the current and next plaintext blocks are affected.
Padding
Required
Code:-
from Crypto.Cipher import DES
from Crypto.Random import get_random_bytes
import base64
def pad(text):
    while len(text) % 8 != 0:
        text += " "
    return text
def unpad(text):
    return text.rstrip()
def generate_des_key():
    return get_random_bytes(8)
def generate_iv():
    return get_random_bytes(8)  # DES block size = 8 bytes
def encrypt_des(plain_text, key, iv):
    des = DES.new(key, DES.MODE_CBC, iv)
    padded_text = pad(plain_text)
    encrypted_text = des.encrypt(padded_text.encode("utf-8"))
    return base64.b64encode(encrypted_text).decode("utf-8")
def decrypt_des(cipher_text, key, iv):
    des = DES.new(key, DES.MODE_CBC, iv)
    decrypted_text = des.decrypt(base64.b64decode(cipher_text))
    return unpad(decrypted_text.decode("utf-8"))
if __name__ == "__main__":
    key = generate_des_key()
    iv = generate_iv()
    print("DES Key (Base64):", base64.b64encode(key).decode())
    print("IV (Base64):", base64.b64encode(iv).decode())
    message = "Hello DES!"
    print("Original Message:", message)
    encrypted = encrypt_des(message, key, iv)
    print("Encrypted (Base64):", encrypted)
    decrypted = decrypt_des(encrypted, key, iv)
    print("Decrypted Message:", decrypted)
Output:-


PRACTICAL NO: 4.2
                                     AES
CBC
CODE:
from Crypto.Cipher import AES
from Crypto.Random import get_random_bytes
import base64
def pad(data):
    pad_len=16-(len(data)%16)
    return data+chr(pad_len) * pad_len
def unpad(data):
    pad_len=ord(data[-1])
    return data[:-pad_len]
def encrypt_aes(palin_text,key):
    iv=get_random_bytes(16)
    cipher=AES.new(key,AES.MODE_CBC,iv)
    padded_text=pad(palin_text)
    encrypted=cipher.encrypt(padded_text.encode('utf-8'))
    return base64.b64encode(iv+encrypted).decode('utf-8')
def decrypt_aes(cipher_text,key):
    raw=base64.b64decode(cipher_text)
    iv=raw[:16]
    encrypted=raw[16:]
    cipher=AES.new(key,AES.MODE_CBC,iv)
    decrypted=cipher.decrypt(encrypted).decode('utf-8')
    return unpad(decrypted)
if __name__=="__main__":
    key=get_random_bytes(16)
    print("AES key (base64):",base64.b64encode(key).decode("utf-8"))
    msg="Hello,AES encryption!"
    print("Original msg:",msg)
    encrypted=encrypt_aes(msg,key)
    print("Encrypted (Base64):",encrypted)
    decrypted=decrypt_aes(encrypted,key)
    print("Decrypted (Base64):",decrypted)
OUTPUT:
ECB
CODE:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad,unpad
key=b'SixteenByteKey12'
data=b'Secure Database Payload Data'
cipher_encrypt=AES.new(key,AES.MODE_ECB)
padded_data=pad(data,AES.block_size)
ciphertext=cipher_encrypt.encrypt(padded_data)
cipher_decrypt=AES.new(key,AES.MODE_ECB)
decrypted_padded=cipher_decrypt.decrypt(ciphertext)
original_data=unpad(decrypted_padded,AES.block_size)
print(f"Ciphertext (Hex) : {ciphertext.hex()}")
print(f"Decrypted Data: {original_data.decode()}")
OUTPUT:
from Crypto.Cipher import AES
from Crypto.Util.Padding import pad, unpad
from Crypto.Random import get_random_bytes
key = b"1234567890abcdef"
iv = get_random_bytes(16)
input_file = "C:/Users/Admin/Downloads/simple.txt"
encrypted_file = "encrypted.bin"
with open(input_file, "rb") as f:
    plaintext = f.read()
cipher = AES.new(key, AES.MODE_CBC, iv)
ciphertext = cipher.encrypt(pad(plaintext, AES.block_size))
with open(encrypted_file, "wb") as f:
    f.write(iv)
    f.write(ciphertext)
print("File encrypted successfully as:", encrypted_file)
decrypted_file = "decrypted_file"  
with open(encrypted_file, "rb") as f:
    iv = f.read(16)          # Read IV
    ciphertext = f.read()    # Read ciphertext
cipher = AES.new(key, AES.MODE_CBC, iv)
decrypted_data = unpad(cipher.decrypt(ciphertext), AES.block_size)
with open(decrypted_file, "wb") as f:
    f.write(decrypted_data)
print("File decrypted successfully as:", decrypted_file)
Output:-
