====== SignatureExtensions ====== **Namespace:** ''WvdS.System.Security.Cryptography.Signatures'' Estensioni Drop-In Replacement per firme digitali con supporto Post-Quantum. Estende ''RSA'', ''ECDsa'' e ''X509Certificate2'' con funzioni di firma ibride PQ. ===== Panoramica ===== Questa classe offre tre tipi di firme: | Modalita | Classico | ML-DSA | Utilizzo | | Classic | ✓ | - | Comportamento standard .NET | | Hybrid | ✓ | ✓ | Massima sicurezza | | PostQuantum | - | ✓ | Puramente post-quantum | ===== RSA SignData/VerifyData ===== using var rsa = RSA.Create(2048); byte[] data = Encoding.UTF8.GetBytes("Dati importanti"); // Firmare con modalita esplicita byte[] signature = rsa.SignData( data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1, CryptoMode.Hybrid); // Verificare bool isValid = rsa.VerifyData( data, signature, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1, CryptoMode.Hybrid); ==== Firma Stream ==== using var fileStream = File.OpenRead("document.pdf"); byte[] signature = rsa.SignData( fileStream, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1, CryptoMode.Hybrid); ===== ECDsa SignData/VerifyData ===== using var ecdsa = ECDsa.Create(ECCurve.NamedCurves.nistP256); byte[] data = GetDataToSign(); // Firmare byte[] signature = ecdsa.SignData( data, HashAlgorithmName.SHA256, CryptoMode.Hybrid); // Verificare bool isValid = ecdsa.VerifyData( data, signature, HashAlgorithmName.SHA256, CryptoMode.Hybrid); ===== Firme basate su certificato ===== var certificate = GetSigningCertificate(); byte[] data = GetDataToSign(); // Firmare (utilizza automaticamente RSA o ECDSA) byte[] signature = certificate.SignData( data, HashAlgorithmName.SHA256, CryptoMode.Hybrid); // Verificare bool isValid = certificate.VerifyData( data, signature, HashAlgorithmName.SHA256, CryptoMode.Hybrid); Il tipo di chiave viene rilevato automaticamente: * Certificato RSA -> RSA.SignData + ML-DSA * Certificato ECDSA -> ECDsa.SignData + ML-DSA ===== Standalone ML-DSA ===== Firme ML-DSA dirette senza chiave classica: // Generare coppia di chiavi var (publicKey, privateKey) = SignatureExtensions.GenerateMlDsaKeyPair(); // Firmare byte[] data = GetDataToSign(); byte[] signature = SignatureExtensions.SignMlDsa(data, privateKey); // Verificare bool isValid = SignatureExtensions.VerifyMlDsa(data, signature, publicKey); ===== Formato firma ibrida ===== ┌────────────────────────────────────────────┐ │ [4 Bytes] Lunghezza firma classica │ │ [n Bytes] Firma classica (RSA/ECDSA) │ │ [m Bytes] Firma PQ (ML-DSA-65) │ └────────────────────────────────────────────┘ ^ Componente ^ Dimensione tipica ^ | Campo lunghezza | 4 Bytes | | Firma RSA-2048 | 256 Bytes | | Firma ECDSA P-256 | ~70 Bytes | | Firma ML-DSA-65 | 3.293 Bytes | | **Hybrid RSA** | **~3.553 Bytes** | | **Hybrid ECDSA** | **~3.367 Bytes** | ===== Chiavi PQ transienti ===== Per firme standalone (senza certificato) vengono utilizzate chiavi transienti thread-local: // Impostare proprie chiavi var (pubKey, privKey) = SignatureExtensions.GenerateMlDsaKeyPair(); SignatureExtensions.SetTransientPqKey(pubKey, privKey); // Ora SignData/VerifyData possono essere utilizzati senza certificato byte[] sig = rsa.SignData(data, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1, CryptoMode.Hybrid); // Solo chiave pubblica per verifica SignatureExtensions.SetTransientPqPublicKey(pubKey); bool valid = rsa.VerifyData(data, sig, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1, CryptoMode.Hybrid); // Pulizia (sovrascrive la chiave privata con zeri) SignatureExtensions.ClearTransientPqKey(); ===== Panoramica metodi ===== ==== Estensioni RSA ==== ^ Metodo ^ Parametri ^ Ritorno ^ | ''SignData(data, hash, padding, mode)'' | byte[], HashAlgorithmName, RSASignaturePadding, CryptoMode? | byte[] | | ''SignData(stream, hash, padding, mode)'' | Stream, HashAlgorithmName, RSASignaturePadding, CryptoMode? | byte[] | | ''VerifyData(data, sig, hash, padding, mode)'' | byte[], byte[], HashAlgorithmName, RSASignaturePadding, CryptoMode? | bool | ==== Estensioni ECDsa ==== ^ Metodo ^ Parametri ^ Ritorno ^ | ''SignData(data, hash, mode)'' | byte[], HashAlgorithmName, CryptoMode? | byte[] | | ''SignData(stream, hash, mode)'' | Stream, HashAlgorithmName, CryptoMode? | byte[] | | ''VerifyData(data, sig, hash, mode)'' | byte[], byte[], HashAlgorithmName, CryptoMode? | bool | ==== Estensioni X509Certificate2 ==== ^ Metodo ^ Parametri ^ Ritorno ^ | ''SignData(data, hash, mode)'' | byte[], HashAlgorithmName, CryptoMode? | byte[] | | ''VerifyData(data, sig, hash, mode)'' | byte[], byte[], HashAlgorithmName, CryptoMode? | bool | ==== Standalone ML-DSA ==== ^ Metodo ^ Parametri ^ Ritorno ^ | ''GenerateMlDsaKeyPair()'' | - | (byte[] PublicKey, byte[] PrivateKey) | | ''SignMlDsa(data, privateKey)'' | byte[], byte[] | byte[] | | ''VerifyMlDsa(data, sig, publicKey)'' | byte[], byte[], byte[] | bool | ==== Gestione chiavi transienti ==== ^ Metodo ^ Descrizione ^ | ''SetTransientPqKey(pub, priv)'' | Imposta coppia di chiavi per thread | | ''SetTransientPqPublicKey(pub)'' | Imposta solo chiave pubblica | | ''ClearTransientPqKey()'' | Cancella chiavi in modo sicuro | ===== Esempio: Workflow completo ===== // 1. Configurare CryptoMode CryptoConfig.DefaultMode = CryptoMode.Hybrid; // 2. Caricare certificato (con chiavi PQ) var cert = X509Certificate2ExportExtensions.ImportPfx( "signing-cert.pfx", "password"); // 3. Firmare documento byte[] documentData = File.ReadAllBytes("contract.pdf"); byte[] signature = cert.SignData(documentData, HashAlgorithmName.SHA256); // 4. Salvare firma File.WriteAllBytes("contract.sig", signature); // 5. Verificare successivamente var verifyCert = new X509Certificate2("signing-cert.cer"); bool isValid = verifyCert.VerifyData( File.ReadAllBytes("contract.pdf"), File.ReadAllBytes("contract.sig"), HashAlgorithmName.SHA256); Console.WriteLine($"Firma valida: {isValid}"); ===== Note di sicurezza ===== * In modalita PostQuantum non viene creata alcuna firma classica - non retrocompatibile * Le chiavi transienti vengono memorizzate thread-local - non condividere tra thread * Chiamare ''ClearTransientPqKey()'' quando le chiavi non sono piu necessarie ===== Vedi anche ===== * [[.:start|Namespace Signatures]] * [[.:signeddataextensions|SignedDataExtensions]] * [[..:x509certificates:x509certificate2extensions|X509Certificate2Extensions]] * [[it:int:pqcrypt:konzepte:algorithmen|Algoritmo ML-DSA]] ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//