Inhaltsverzeichnis

SignatureExtensions

Namespace: WvdS.System.Security.Cryptography.Signatures

Drop-In Replacement razširitve za digitalne podpise s podporo za post-kvantno kriptografijo. Razširja RSA, ECDsa in X509Certificate2 s PQ-hibridnimi funkcijami podpisovanja.

Pregled

Ta razred ponuja tri vrste podpisov:

Način Klasičen ML-DSA Uporaba
Classic - Standardno .NET obnašanje
Hybrid Maksimalna varnost
PostQuantum - Čisto post-kvantno

RSA SignData/VerifyData

using var rsa = RSA.Create(2048);
byte[] data = Encoding.UTF8.GetBytes("Pomembni podatki");
 
// Podpisovanje z eksplicitnim načinom
byte[] signature = rsa.SignData(
    data,
    HashAlgorithmName.SHA256,
    RSASignaturePadding.Pkcs1,
    CryptoMode.Hybrid);
 
// Preverjanje
bool isValid = rsa.VerifyData(
    data,
    signature,
    HashAlgorithmName.SHA256,
    RSASignaturePadding.Pkcs1,
    CryptoMode.Hybrid);

Tokovni podpis

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();
 
// Podpisovanje
byte[] signature = ecdsa.SignData(
    data,
    HashAlgorithmName.SHA256,
    CryptoMode.Hybrid);
 
// Preverjanje
bool isValid = ecdsa.VerifyData(
    data,
    signature,
    HashAlgorithmName.SHA256,
    CryptoMode.Hybrid);

Podpisi na osnovi certifikatov

var certificate = GetSigningCertificate();
byte[] data = GetDataToSign();
 
// Podpisovanje (samodejno uporablja RSA ali ECDSA)
byte[] signature = certificate.SignData(
    data,
    HashAlgorithmName.SHA256,
    CryptoMode.Hybrid);
 
// Preverjanje
bool isValid = certificate.VerifyData(
    data,
    signature,
    HashAlgorithmName.SHA256,
    CryptoMode.Hybrid);

Tip ključa je samodejno prepoznan:

Samostojni ML-DSA

Neposredni ML-DSA podpisi brez klasičnega ključa:

// Generiranje para ključev
var (publicKey, privateKey) = SignatureExtensions.GenerateMlDsaKeyPair();
 
// Podpisovanje
byte[] data = GetDataToSign();
byte[] signature = SignatureExtensions.SignMlDsa(data, privateKey);
 
// Preverjanje
bool isValid = SignatureExtensions.VerifyMlDsa(data, signature, publicKey);

Hibridni format podpisa

┌────────────────────────────────────────────┐
│ [4 bajti] Dolžina klasičnega podpisa       │
│ [n bajtov] Klasični podpis (RSA/ECDSA)     │
│ [m bajtov] PQ-podpis (ML-DSA-65)           │
└────────────────────────────────────────────┘
Komponenta Tipična velikost
Polje dolžine 4 bajti
RSA-2048 podpis 256 bajtov
ECDSA P-256 podpis ~70 bajtov
ML-DSA-65 podpis 3.293 bajtov
Hibridni RSA ~3.553 bajtov
Hibridni ECDSA ~3.367 bajtov

Začasni PQ-ključi

Za samostojne podpise (brez certifikata) se uporabljajo nitno-lokalni začasni ključi:

// Nastavitev lastnih ključev
var (pubKey, privKey) = SignatureExtensions.GenerateMlDsaKeyPair();
SignatureExtensions.SetTransientPqKey(pubKey, privKey);
 
// Zdaj se lahko SignData/VerifyData uporabljata brez certifikata
byte[] sig = rsa.SignData(data, HashAlgorithmName.SHA256,
    RSASignaturePadding.Pkcs1, CryptoMode.Hybrid);
 
// Samo javni ključ za preverjanje
SignatureExtensions.SetTransientPqPublicKey(pubKey);
bool valid = rsa.VerifyData(data, sig, HashAlgorithmName.SHA256,
    RSASignaturePadding.Pkcs1, CryptoMode.Hybrid);
 
// Čiščenje (prepiše zasebni ključ z ničlami)
SignatureExtensions.ClearTransientPqKey();

Pregled metod

RSA razširitve

Metoda Parametri Vrnjeno
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

ECDsa razširitve

Metoda Parametri Vrnjeno
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

X509Certificate2 razširitve

Metoda Parametri Vrnjeno
SignData(data, hash, mode) byte[], HashAlgorithmName, CryptoMode? byte[]
VerifyData(data, sig, hash, mode) byte[], byte[], HashAlgorithmName, CryptoMode? bool

Samostojni ML-DSA

Metoda Parametri Vrnjeno
GenerateMlDsaKeyPair() - (byte[] PublicKey, byte[] PrivateKey)
SignMlDsa(data, privateKey) byte[], byte[] byte[]
VerifyMlDsa(data, sig, publicKey) byte[], byte[], byte[] bool

Upravljanje začasnih ključev

Metoda Opis
SetTransientPqKey(pub, priv) Nastavi par ključev za nit
SetTransientPqPublicKey(pub) Nastavi samo javni ključ
ClearTransientPqKey() Varno izbriše ključe

Primer: Popoln potek dela

// 1. Konfiguracija CryptoMode
CryptoConfig.DefaultMode = CryptoMode.Hybrid;
 
// 2. Nalaganje certifikata (s PQ-ključi)
var cert = X509Certificate2ExportExtensions.ImportPfx(
    "signing-cert.pfx",
    "password");
 
// 3. Podpisovanje dokumenta
byte[] documentData = File.ReadAllBytes("contract.pdf");
byte[] signature = cert.SignData(documentData, HashAlgorithmName.SHA256);
 
// 4. Shranjevanje podpisa
File.WriteAllBytes("contract.sig", signature);
 
// 5. Kasnejše preverjanje
var verifyCert = new X509Certificate2("signing-cert.cer");
bool isValid = verifyCert.VerifyData(
    File.ReadAllBytes("contract.pdf"),
    File.ReadAllBytes("contract.sig"),
    HashAlgorithmName.SHA256);
 
Console.WriteLine($"Podpis veljaven: {isValid}");

Varnostni nasveti

  • V načinu PostQuantum ni ustvarjen klasični podpis - ni nazaj združljivo
  • Začasni ključi so shranjeni nitno-lokalno - ne delite med nitmi
  • Pokličite ClearTransientPqKey() ko ključi niso več potrebni

Glej tudi


Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional