~~NOTOC~~
====== Scenarij 8.1: Potpisivanje dokumenata ======
**Kategorija:** [[.:start|Digitalni potpisi]] \\
**Složenost:** ⭐⭐⭐ (Srednja) \\
**Preduvjeti:** Certifikat i ključ za potpisivanje \\
**Procijenjeno vrijeme:** 15-20 minuta
----
===== Opis =====
Ovaj scenarij opisuje **digitalno potpisivanje dokumenata** s Post-Quantum-sigurnim algoritmima (ML-DSA). Digitalni potpisi jamče:
* **Autentičnost** - Pošiljatelj je verificiran
* **Integritet** - Dokument nije izmijenjen
* **Neporecivost** - Potpis se ne može poricati
**Podržani formati:**
* Detached Signature (zasebna .sig datoteka)
* CMS/PKCS#7 (ugrađen ili detached)
* PDF Digital Signature (PAdES)
----
===== Tijek rada =====
flowchart LR
DOC[Dokument] --> HASH[SHA-256 Hash]
HASH --> SIGN[ML-DSA Potpis]
KEY[Privatni ključ] --> SIGN
SIGN --> SIG[Potpis]
CERT[Certifikat] --> CMS[CMS Container]
SIG --> CMS
style SIGN fill:#e8f5e9
style CMS fill:#e3f2fd
----
===== Primjer koda: Detached Signature =====
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Security.Cryptography;
using var ctx = PqCryptoContext.Initialize();
// Učitavanje ključa za potpisivanje
var signingKey = ctx.LoadPrivateKey("signing.key.pem", "KeyPassword!");
var signingCert = ctx.LoadCertificate("signing.crt.pem");
// Učitavanje dokumenta
var document = File.ReadAllBytes("contract.pdf");
// Izračun hasha
var hash = SHA256.HashData(document);
// Potpisivanje s ML-DSA
var signature = ctx.SignData(
data: hash,
privateKey: signingKey,
hashAlgorithm: HashAlgorithmName.SHA256,
mode: CryptoMode.Hybrid // RSA + ML-DSA paralelno
);
// Spremanje potpisa
File.WriteAllBytes("contract.pdf.sig", signature);
// Metapodaci potpisa
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 potpisan:");
Console.WriteLine($" Potpisnik: {signingCert.Subject}");
Console.WriteLine($" Hash: {Convert.ToHexString(hash).Substring(0, 16)}...");
Console.WriteLine($" Potpis: {signature.Length} bajta");
----
===== Primjer koda: CMS/PKCS#7 potpis =====
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");
// Kreiranje CMS ContentInfo
var contentInfo = new ContentInfo(document);
// Kreiranje SignedCms
var signedCms = new SignedCms(contentInfo, detached: false); // Ugrađen
// 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
};
// Dodavanje potpisanih atributa
signer.SignedAttributes.Add(new Pkcs9SigningTime(DateTimeOffset.UtcNow));
// Potpisivanje s PQ-ekstenzijom (Hybrid)
signedCms.ComputeSignature(signer, mode: CryptoMode.Hybrid);
// Izvoz CMS Containera
var signedData = signedCms.Encode();
File.WriteAllBytes("contract.pdf.p7s", signedData);
Console.WriteLine($"CMS Potpis kreiran: {signedData.Length} bajta");
----
===== Primjer koda: Verifikacija potpisa =====
using var ctx = PqCryptoContext.Initialize();
// Učitavanje dokumenta i potpisa
var document = File.ReadAllBytes("contract.pdf");
var signature = File.ReadAllBytes("contract.pdf.sig");
// Učitavanje certifikata potpisnika
var signerCert = ctx.LoadCertificate("signing.crt.pem");
// Izračun hasha
var hash = SHA256.HashData(document);
// Verifikacija potpisa
bool isValid = ctx.VerifyData(
data: hash,
signature: signature,
certificate: signerCert,
hashAlgorithm: HashAlgorithmName.SHA256,
mode: CryptoMode.Hybrid
);
Console.WriteLine($"Potpis valjan: {isValid}");
if (isValid)
{
// Validacija lanca certifikata
var chain = new X509Chain();
chain.ChainPolicy.RevocationMode = X509RevocationMode.Online;
bool chainValid = chain.Build(signerCert);
Console.WriteLine($"Certifikat valjan: {chainValid}");
Console.WriteLine($" Potpisnik: {signerCert.Subject}");
Console.WriteLine($" Vrijedi do: {signerCert.NotAfter:yyyy-MM-dd}");
}
----
===== Grupno potpisivanje =====
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 potpisa =====
^ Format ^ Standard ^ Uporaba ^ Ugrađen ^
| Detached | Proprietarni | Jednostavni slučajevi | Ne |
| PKCS#7/CMS | RFC 5652 | E-mail, Dokumenti | Opcionalno |
| PAdES | ETSI TS 103 172 | PDF potpisi | Da |
| XAdES | ETSI TS 101 903 | XML potpisi | Opcionalno |
| JAdES | ETSI TS 119 182 | JSON potpisi | Opcionalno |
----
===== Zahtjevi specifični za industriju =====
^ Industrija ^ Standard ^ Format ^ Posebnost ^
| **eIDAS** | Kvalificirani potpis | PAdES-LTA | Dugoročno arhiviranje |
| **Zdravstvo** | DiGAV | CMS | Dokumentacija pacijenata |
| **Financije** | PSD2 | JAdES | API potpisi |
| **Vlada** | eGovG | XAdES | Upravni dokumenti |
----
===== Povezani scenariji =====
^ Povezanost ^ Scenarij ^ Opis ^
| **Povezano** | [[.:code_signieren|8.2 Potpisivanje koda]] | Potpisivanje izvršnih datoteka |
| **Povezano** | [[.:timestamp|8.3 Vremenska oznaka]] | Dugoročna valjanost |
| **Sljedeći korak** | [[.:signatur_verifizieren|8.4 Verifikacija potpisa]] | Provjera |
----
<< [[.:start|← Pregled potpisa]] | [[hr:int:pqcrypt:szenarien:start|↑ Scenariji]] | [[.:code_signieren|8.2 Potpisivanje koda →]] >>
{{tag>scenarij potpis dokument cms pkcs7 ml-dsa}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//