# compatibile Windows 11 # compatibile Ubuntu 24.10 # compatibile python 3.12.7 import os from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding from cryptography.exceptions import InvalidTag, InvalidSignature def encrypt_aes_cbc_pkcs7(plaintext, key, iv): """ Crittografa un messaggio usando AES-CBC con padding PKCS7. Args: plaintext (bytes): Il messaggio in chiaro da crittografare. key (bytes): La chiave AES (32 byte per AES-256). iv (bytes): Il vettore di inizializzazione (16 byte). Returns: bytes: Il testo cifrato. Raises: TypeError: Se plaintext, key o iv non sono di tipo bytes. ValueError: Se la chiave non ha la lunghezza corretta. """ if not isinstance(plaintext, bytes): raise TypeError("plaintext deve essere di tipo bytes") if not isinstance(key, bytes): raise TypeError("key deve essere di tipo bytes") if not isinstance(iv, bytes): raise TypeError("iv deve essere di tipo bytes") if len(key) != 32: raise ValueError("La chiave deve essere di 32 byte (256 bit) per AES-256") # Crea un oggetto Cipher per AES-CBC cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) encryptor = cipher.encryptor() # Crea un oggetto Padder per PKCS7 padder = padding.PKCS7(algorithms.AES.block_size).padder() # Applica il padding al plaintext padded_plaintext = padder.update(plaintext) + padder.finalize() # Crittografa il plaintext con padding ciphertext = encryptor.update(padded_plaintext) + encryptor.finalize() return ciphertext def decrypt_aes_cbc_pkcs7(ciphertext, key, iv): """ Decrittografa un messaggio crittografato con AES-CBC e padding PKCS7. Args: ciphertext (bytes): Il testo cifrato da decrittografare. key (bytes): La chiave AES (32 byte per AES-256). iv (bytes): Il vettore di inizializzazione (16 byte). Returns: bytes: Il messaggio in chiaro decrittografato. Raises: TypeError: Se ciphertext, key o iv non sono di tipo bytes. ValueError: Se la chiave non ha la lunghezza corretta, o se il padding รจ invalido. """ if not isinstance(ciphertext, bytes): raise TypeError("ciphertext deve essere di tipo bytes") if not isinstance(key, bytes): raise TypeError("key deve essere di tipo bytes") if not isinstance(iv, bytes): raise TypeError("iv deve essere di tipo bytes") if len(key) != 32: raise ValueError("La chiave deve essere di 32 byte (256 bit) per AES-256") # Crea un oggetto Cipher per AES-CBC cipher = Cipher(algorithms.AES(key), modes.CBC(iv), backend=default_backend()) decryptor = cipher.decryptor() # Decrittografa il ciphertext decrypted_data = decryptor.update(ciphertext) + decryptor.finalize() # Crea un oggetto Unpadder per PKCS7 unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() # Rimuovi il padding try: plaintext = unpadder.update(decrypted_data) + unpadder.finalize() except ValueError as e: # Gestisci padding invalido raise ValueError("Padding invalido o dati corrotti.") from e return plaintext def main(): # Genera chiave e IV casuali key = os.urandom(32) # Chiave a 256 bit per AES-256 iv = os.urandom(16) # IV di 16 byte (dimensione blocco AES) # Testi in chiaro di esempio plaintexts = [ b"SHORT", b"MEDIUM MEDIUM MEDIUM", b"LONG LONG LONG LONG LONG LONG", b"" # Caso di messaggio vuoto ] print("--- Test di Crittografia e Decrittografia AES-CBC con Padding PKCS7 ---") for plaintext in plaintexts: # Crittografa ciphertext = encrypt_aes_cbc_pkcs7(plaintext, key, iv) # Decrittografa decrypted_plaintext = decrypt_aes_cbc_pkcs7(ciphertext, key, iv) # Verifica if plaintext == decrypted_plaintext: print(f"[PASS] Test con plaintext di lunghezza {len(plaintext)} bytes: '{plaintext.decode('utf-8', errors='ignore')}'") else: print(f"[FAIL] Test con plaintext di lunghezza {len(plaintext)} bytes: '{plaintext.decode('utf-8', errors='ignore')}'") print(f" Originale: {plaintext}") print(f" Decrittato: {decrypted_plaintext}") if __name__ == "__main__": main()