# compatibile Windows 11 # compatibile Ubuntu 24.10 # compatibile python 3.12.7 import os import hashlib from cryptography.hazmat.primitives.ciphers import Cipher, algorithms, modes from cryptography.hazmat.backends import default_backend from cryptography.hazmat.primitives import padding from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC import base64 def genera_chiave_aes(password_testo, sale): """ Genera una chiave AES-256 derivata da una password di testo utilizzando PBKDF2HMAC. Args: password_testo (str): La password di testo da cui derivare la chiave. sale (bytes): Un sale casuale per rafforzare la derivazione della chiave. Returns: bytes: Una chiave AES-256 di 32 byte. """ password = password_testo.encode('utf-8') # Codifica la password in bytes kdf = PBKDF2HMAC( algorithm=hashes.SHA256(), # Utilizza SHA256 come algoritmo di hash length=32, # Lunghezza desiderata della chiave: 32 byte (256 bit) per AES-256 salt=sale, # Utilizza il sale fornito iterations=100000, # Numero di iterazioni per PBKDF2 (rende la derivazione più lenta e più sicura) backend=default_backend() # Utilizza il backend di crittografia predefinito ) chiave = kdf.derive(password) # Deriva la chiave dalla password e dal sale return base64.urlsafe_b64encode(chiave) # Codifica la chiave in Base64URL per la memorizzazione/trasmissione (opzionale) def crittografa_aes_cbc(plaintext, chiave_bytes): """ Crittografa il plaintext utilizzando AES-256 in modalità CBC con padding PKCS7. Args: plaintext (bytes): I dati in chiaro da crittografare. chiave_bytes (bytes): La chiave di crittografia AES-256 (32 byte). Returns: tuple: Una tupla contenente (iv, ciphertext). iv (bytes): Il vettore di inizializzazione (IV) casuale. ciphertext (bytes): I dati crittografati. """ iv = os.urandom(16) # Genera un IV casuale di 16 byte per CBC cipher = Cipher(algorithms.AES(base64.urlsafe_b64decode(chiave_bytes)), modes.CBC(iv), backend=default_backend()) # Crea un oggetto Cipher AES in modalità CBC encryptor = cipher.encryptor() # Crea un encryptor padder = padding.PKCS7(algorithms.AES.block_size).padder() # Crea un padder PKCS7 padded_data = padder.update(plaintext) + padder.finalize() # Applica il padding al plaintext ciphertext = encryptor.update(padded_data) + encryptor.finalize() # Crittografa i dati padded return iv, ciphertext # Restituisce IV e ciphertext def decrittografa_aes_cbc(ciphertext, chiave_bytes, iv): """ Decrittografa il ciphertext crittografato con AES-256 in modalità CBC. Args: ciphertext (bytes): I dati crittografati da decrittografare. chiave_bytes (bytes): La chiave di decrittografia AES-256 (32 byte). iv (bytes): Il vettore di inizializzazione (IV) utilizzato per la crittografia. Returns: bytes: I dati in chiaro decrittografati. """ cipher = Cipher(algorithms.AES(base64.urlsafe_b64decode(chiave_bytes)), modes.CBC(iv), backend=default_backend()) # Crea un oggetto Cipher AES in modalità CBC decryptor = cipher.decryptor() # Crea un decryptor unpadder = padding.PKCS7(algorithms.AES.block_size).unpadder() # Crea un unpadder PKCS7 padded_data = decryptor.update(ciphertext) + decryptor.finalize() # Decrittografa i dati cifrati plaintext = unpadder.update(padded_data) + unpadder.finalize() # Rimuove il padding return plaintext # Restituisce il plaintext decrittografato def main(): """ Funzione principale per dimostrare la crittografia e la decrittografia AES-CBC. """ password_testo = "LaMiaPasswordSegretaMoltoForte123" # Password di esempio (sostituiscila con una più sicura nella realtà) sale = os.urandom(16) # Genera un sale casuale di 16 byte chiave_bytes = genera_chiave_aes(password_testo, sale) # Genera la chiave AES dai bytes della password plaintext_testo = "Questo è un messaggio di testo di esempio che verrà crittografato con AES-CBC." # Testo in chiaro di esempio plaintext_bytes = plaintext_testo.encode('utf-8') # Codifica il plaintext in bytes iv, ciphertext = crittografa_aes_cbc(plaintext_bytes, chiave_bytes) # Crittografa il plaintext print("Testo in chiaro originale:", plaintext_testo) print("Chiave (Base64URL):", chiave_bytes.decode('utf-8')) # Stampa la chiave codificata in Base64URL print("IV (Hex):", iv.hex()) # Stampa l'IV in formato esadecimale print("Testo cifrato (Hex):", ciphertext.hex()) # Stampa il ciphertext in formato esadecimale decrypted_plaintext_bytes = decrittografa_aes_cbc(ciphertext, chiave_bytes, iv) # Decrittografa il ciphertext decrypted_plaintext_testo = decrypted_plaintext_bytes.decode('utf-8') # Decodifica il plaintext decrittografato in testo print("Testo in chiaro decrittografato:", decrypted_plaintext_testo) # Verifica che il plaintext decrittografato corrisponda all'originale if decrypted_plaintext_testo == plaintext_testo: print("\nCrittografia e decrittografia AES-CBC riuscite!") else: print("\nErrore: la decrittografia non ha prodotto il plaintext originale.") if __name__ == "__main__": main()