~~NOTOC~~ ====== Scenarij 8.1: Podpisovanje dokumentov ====== **Kategorija:** [[.:start|Digitalni podpisi]] \\ **Kompleksnost:** ⭐⭐⭐ (Srednja) \\ **Predpogoji:** Certifikat in ključ za podpisovanje \\ **Predviden čas:** 15-20 minut ---- ===== Opis ===== Ta scenarij opisuje **digitalno podpisovanje dokumentov** s postkvantno varnimi algoritmi (ML-DSA). Digitalni podpisi zagotavljajo: * **Avtentičnost** - Pošiljatelj je verificiran * **Celovitost** - Dokument ni bil spremenjen * **Nezmožnost zanikanja** - Podpisa ni mogoče zanikati **Podprti formati:** * Ločen podpis (separate .sig datoteka) * CMS/PKCS#7 (vgrajen ali ločen) * PDF digitalni podpis (PAdES) ---- ===== Potek dela ===== flowchart LR DOC[Dokument] --> HASH[SHA-256 zgoščena vrednost] HASH --> SIGN[ML-DSA podpis] KEY[Zasebni ključ] --> SIGN SIGN --> SIG[Podpis] CERT[Certifikat] --> CMS[CMS vsebnik] SIG --> CMS style SIGN fill:#e8f5e9 style CMS fill:#e3f2fd ---- ===== Primer kode: Ločen podpis ===== using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Security.Cryptography; using var ctx = PqCryptoContext.Initialize(); // Nalaganje podpisnega ključa var signingKey = ctx.LoadPrivateKey("signing.key.pem", "KeyPassword!"); var signingCert = ctx.LoadCertificate("signing.crt.pem"); // Nalaganje dokumenta var document = File.ReadAllBytes("contract.pdf"); // Izračun zgoščene vrednosti var hash = SHA256.HashData(document); // Podpisovanje z ML-DSA var signature = ctx.SignData( data: hash, privateKey: signingKey, hashAlgorithm: HashAlgorithmName.SHA256, mode: CryptoMode.Hybrid // RSA + ML-DSA vzporedno ); // Shranjevanje podpisa File.WriteAllBytes("contract.pdf.sig", signature); // Metapodatki podpisa var sigInfo = new SignatureInfo { Algorithm = "ML-DSA-65 + RSA-PSS (Hybrid)", SignedAt = DateTimeOffset.UtcNow, Signer = signingCert.Subject, DocumentHash = Convert.ToHexString(hash), SignatureFile = "contract.pdf.sig" }; File.WriteAllText("contract.pdf.sig.json", JsonSerializer.Serialize(sigInfo, new JsonSerializerOptions { WriteIndented = true })); Console.WriteLine($"Dokument podpisan:"); Console.WriteLine($" Podpisnik: {signingCert.Subject}"); Console.WriteLine($" Zgoščena vrednost: {Convert.ToHexString(hash).Substring(0, 16)}..."); Console.WriteLine($" Podpis: {signature.Length} bajtov"); ---- ===== Primer kode: CMS/PKCS#7 podpis ===== using System.Security.Cryptography.Pkcs; using var ctx = PqCryptoContext.Initialize(); var signingCert = ctx.LoadCertificate("signing.crt.pem"); var signingKey = ctx.LoadPrivateKey("signing.key.pem", "KeyPassword!"); // Dokument var document = File.ReadAllBytes("contract.pdf"); // Ustvarjanje CMS ContentInfo var contentInfo = new ContentInfo(document); // Ustvarjanje SignedCms var signedCms = new SignedCms(contentInfo, detached: false); // Vgrajeno // Konfiguracija Signer-Info var signer = new CmsSigner(signingCert) { DigestAlgorithm = new Oid("2.16.840.1.101.3.4.2.1"), // SHA-256 IncludeOption = X509IncludeOption.WholeChain }; // Dodajanje podpisanih atributov signer.SignedAttributes.Add(new Pkcs9SigningTime(DateTimeOffset.UtcNow)); // Podpisovanje s PQ razširitvijo (hibridno) signedCms.ComputeSignature(signer, mode: CryptoMode.Hybrid); // Izvoz CMS vsebnika var signedData = signedCms.Encode(); File.WriteAllBytes("contract.pdf.p7s", signedData); Console.WriteLine($"CMS podpis ustvarjen: {signedData.Length} bajtov"); ---- ===== Primer kode: Verifikacija podpisa ===== using var ctx = PqCryptoContext.Initialize(); // Nalaganje dokumenta in podpisa var document = File.ReadAllBytes("contract.pdf"); var signature = File.ReadAllBytes("contract.pdf.sig"); // Nalaganje certifikata podpisnika var signerCert = ctx.LoadCertificate("signing.crt.pem"); // Izračun zgoščene vrednosti var hash = SHA256.HashData(document); // Verifikacija podpisa bool isValid = ctx.VerifyData( data: hash, signature: signature, certificate: signerCert, hashAlgorithm: HashAlgorithmName.SHA256, mode: CryptoMode.Hybrid ); Console.WriteLine($"Podpis veljaven: {isValid}"); if (isValid) { // Validacija verige certifikatov var chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; bool chainValid = chain.Build(signerCert); Console.WriteLine($"Certifikat veljaven: {chainValid}"); Console.WriteLine($" Podpisnik: {signerCert.Subject}"); Console.WriteLine($" Veljavno do: {signerCert.NotAfter:yyyy-MM-dd}"); } ---- ===== Paketno podpisovanje ===== public class BatchSigner { private readonly AsymmetricAlgorithm _signingKey; private readonly X509Certificate2 _signingCert; private readonly PqCryptoContext _ctx; public BatchSigner(string certPath, string keyPath, string password) { _ctx = PqCryptoContext.Initialize(); _signingCert = _ctx.LoadCertificate(certPath); _signingKey = _ctx.LoadPrivateKey(keyPath, password); } public async Task> SignBatch(IEnumerable filePaths) { var results = new List(); foreach (var filePath in filePaths) { try { var document = await File.ReadAllBytesAsync(filePath); var hash = SHA256.HashData(document); var signature = _ctx.SignData( hash, _signingKey, HashAlgorithmName.SHA256, CryptoMode.Hybrid ); var sigPath = filePath + ".sig"; await File.WriteAllBytesAsync(sigPath, signature); results.Add(new SignatureResult { FilePath = filePath, SignaturePath = sigPath, Success = true, SignedAt = DateTimeOffset.UtcNow }); } catch (Exception ex) { results.Add(new SignatureResult { FilePath = filePath, Success = false, Error = ex.Message }); } } return results; } } ---- ===== Formati podpisov ===== ^ Format ^ Standard ^ Uporaba ^ Vgrajeno ^ | Ločen | Lastniški | Enostavni primeri | Ne | | PKCS#7/CMS | RFC 5652 | E-pošta, dokumenti | Opcijsko | | PAdES | ETSI TS 103 172 | PDF podpisi | Da | | XAdES | ETSI TS 101 903 | XML podpisi | Opcijsko | | JAdES | ETSI TS 119 182 | JSON podpisi | Opcijsko | ---- ===== Panožne zahteve ===== ^ Panoga ^ Standard ^ Format ^ Posebnost ^ | **eIDAS** | Kvalificiran podpis | PAdES-LTA | Dolgoročno arhiviranje | | **Zdravstvo** | DiGAV | CMS | Pacientska dokumentacija | | **Finance** | PSD2 | JAdES | API podpisi | | **Vlada** | eGovG | XAdES | Upravni dokumenti | ---- ===== Povezani scenariji ===== ^ Povezava ^ Scenarij ^ Opis ^ | **Povezano** | [[.:code_signieren|8.2 Podpisovanje kode]] | Podpisovanje izvršljivih datotek | | **Povezano** | [[.:timestamp|8.3 Časovni žig]] | Dolgoročna veljavnost | | **Naslednji korak** | [[.:signatur_verifizieren|8.4 Verifikacija podpisa]] | Preverjanje | ---- << [[.:start|← Pregled podpisov]] | [[sl:int:pqcrypt:szenarien:start|↑ Scenariji]] | [[.:code_signieren|8.2 Podpisovanje kode →]] >> {{tag>scenarij podpis dokument cms pkcs7 ml-dsa}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//