# compatibile Windows 11 # compatibile Ubuntu 24.10 # compatibile python 3.12.7 import os from typing import Tuple from cryptography.hazmat.primitives import hashes from cryptography.hazmat.primitives.asymmetric import dsa from cryptography.hazmat.primitives.asymmetric import padding # Importa padding from cryptography.exceptions import InvalidSignature from cryptography.hazmat.primitives import serialization from cryptography.hazmat.backends import default_backend def generate_parameters(key_size: int = 2048) -> dsa.DSAParameters: """ Genera i parametri DSA. Args: key_size: La dimensione della chiave (default: 2048). Returns: I parametri DSA. """ parameters = dsa.generate_parameters(key_size=key_size, backend=default_backend()) return parameters def generate_keypair(parameters: dsa.DSAParameters) -> Tuple[dsa.DSAPrivateKey, dsa.DSAPublicKey]: """ Genera una coppia di chiavi DSA (privata, pubblica). Args: parameters: I parametri DSA. Returns: Una tupla (private_key, public_key). """ private_key = parameters.generate_private_key() public_key = private_key.public_key() return private_key, public_key def sign(message: bytes, private_key: dsa.DSAPrivateKey) -> bytes: """ Firma un messaggio usando DSA. Args: message: Il messaggio da firmare (bytes). private_key: La chiave privata DSA. Returns: La firma digitale (bytes). """ signature = private_key.sign(message, hashes.SHA256()) return signature def verify(message: bytes, signature: bytes, public_key: dsa.DSAPublicKey) -> bool: """ Verifica una firma DSA. Args: message: Il messaggio originale (bytes). signature: La firma (bytes). public_key: La chiave pubblica DSA. Returns: True se la firma è valida, False altrimenti. """ try: public_key.verify(signature, message, hashes.SHA256()) return True except InvalidSignature: return False except Exception as e: print(f"Errore durante la verifica: {e}") # Stampa altri errori return False def serialize_key(key, private: bool = False, password: str = None) -> bytes: """ Serializza la chiave (privata o pubblica) in formato PEM. Args: key: La chiave da serializzare. private: True per chiave privata, False per pubblica. password: Password per proteggere la chiave privata (opzionale). Returns: La chiave serializzata in formato PEM (bytes). """ if private: if password: encryption_algorithm = serialization.BestAvailableEncryption(password.encode()) else: encryption_algorithm = serialization.NoEncryption() pem = key.private_bytes( encoding=serialization.Encoding.PEM, format=serialization.PrivateFormat.PKCS8, encryption_algorithm=encryption_algorithm ) else: pem = key.public_bytes( encoding = serialization.Encoding.PEM, format = serialization.PublicFormat.SubjectPublicKeyInfo ) return pem def deserialize_key(pem:bytes, private:bool = False, password: str = None): """ Deserializza una chiave dal formato PEM Args: pem: La chiave in formato PEM (bytes). private: True se la chiave è privata, False se pubblica. password: Password per la chiave privata crittografata (opzionale). Returns: La chiave deserializzata. """ if private: if password: key = serialization.load_pem_private_key( pem, password = password.encode(), backend=default_backend() ) else: key = serialization.load_pem_private_key( pem, password = None, backend = default_backend() ) else: key = serialization.load_pem_public_key( pem, backend = default_backend() ) return key def clear_screen(): """Pulisce lo schermo della console (sia Windows che Unix-like).""" os.system('cls' if os.name == 'nt' else 'clear') def main(): """Funzione principale del programma dimostrativo.""" clear_screen() print("=" * 50) print(" Dimostrazione dell'algoritmo DSA con 'cryptography'") print("=" * 50) # 1. Generazione dei parametri print("\n1. Generazione dei parametri...") key_size = 0 while key_size not in [1024, 2048, 3072]: try: key_size = int(input(" Inserisci la dimensione della chiave (1024, 2048, 3072): ")) if key_size not in [1024, 2048, 3072]: print(" Errore: la dimensione della chiave deve essere 1024, 2048 o 3072.") except ValueError: print(" Errore: inserisci un numero intero.") parameters = generate_parameters(key_size) print(" Parametri generati.") # 2. Generazione delle chiavi print("\n2. Generazione delle chiavi...") private_key, public_key = generate_keypair(parameters) print(" Chiavi generate.") # Serializzazione (esempio) private_pem = serialize_key(private_key, private=True, password="password") public_pem = serialize_key(public_key) print("\n Chiave privata PEM (protetta da password):") print(private_pem.decode()) print("\n Chiave pubblica PEM:") print(public_pem.decode()) # 3. Firma print("\n3. Firma del messaggio...") message = input(" Inserisci il messaggio da firmare: ").encode('utf-8') signature = sign(message, private_key) print(f" Firma (bytes): {signature.hex()}") # 4. Verifica print("\n4. Verifica della firma...") is_valid = verify(message, signature, public_key) if is_valid: print(" [SUCCESS] La firma è valida.") else: print(" [ERRORE] La firma NON è valida.") # 5. Deserializzazione (esempio) print("\n5. Deserializzazione delle chiavi (esempio)...") deserialized_private_key = deserialize_key(private_pem, private=True, password="password") deserialized_public_key = deserialize_key(public_pem) # Verifica che le chiavi deserializzate siano uguali a quelle originali. # Per gli oggetti chiave, usa i numeri pubblici/privati per la comparazione. if private_key.private_numbers() == deserialized_private_key.private_numbers(): print(" Chiave privata deserializzata correttamente.") else: print(" Errore nella deserializzazione della chiave privata.") if public_key.public_numbers() == deserialized_public_key.public_numbers(): print(" Chiave pubblica deserializzata correttamente.") else: print(" Errore nella deserializzazione della chiave pubblica.") print("=" * 50) if __name__ == "__main__": main()