====== 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//