====== RevocationExtensions Klasa ====== Extension Methods za provjeru opoziva certifikata. ---- ===== Definicija ===== namespace WvdS.System.Security.Cryptography.X509Certificates; public static class RevocationExtensions ---- ===== Metode ===== ^ Metoda ^ Opis ^ | IsRevoked | Provjerava je li certifikat opozvan | | FetchCrlAsync | Učitava CRL s URL-a (iz ekstenzije certifikata) | | CheckRevocationAsync | Kombinirano: Učitavanje CRL-a i provjera opoziva | | GetCrlDistributionPoints | Ekstrahira CRL URL-ove iz certifikata | | GetOcspUrls | Ekstrahira OCSP URL-ove iz certifikata | ---- ===== Provjera opoziva ===== **S postojećim CRL-om:** using System.Security.Cryptography.X509Certificates; using WvdS.System.Security.Cryptography.X509Certificates; var certificate = new X509Certificate2("user.cer"); byte[] crlData = File.ReadAllBytes("ca.crl"); var caCert = new X509Certificate2("ca.cer"); // Provjera s verifikacijom potpisa RevocationResult result = certificate.IsRevoked(crlData, caCert, CryptoMode.Hybrid); if (result.Success) { if (result.IsRevoked) { Console.WriteLine($"Certifikat opozvan dana: {result.RevocationDate}"); Console.WriteLine($"Razlog: {result.Reason}"); } else { Console.WriteLine("Certifikat je valjan"); } } else { Console.WriteLine($"Greška: {result.ErrorMessage}"); } **Automatsko učitavanje CRL-a:** // Učitava CRL s URL-a iz CDP ekstenzije certifikata RevocationResult result = await certificate.CheckRevocationAsync( caCert, mode: CryptoMode.Hybrid); ---- ===== Učitavanje CRL-a ===== // Samo učitavanje CRL-a, bez provjere byte[]? crlData = await certificate.FetchCrlAsync(); if (crlData != null) { File.WriteAllBytes("downloaded.crl", crlData); } **S vlastitim HttpClientom:** using var httpClient = new HttpClient(); httpClient.Timeout = TimeSpan.FromSeconds(10); byte[]? crlData = await certificate.FetchCrlAsync(httpClient); ---- ===== Čitanje CRL Distribution Points ===== IReadOnlyList crlUrls = certificate.GetCrlDistributionPoints(); foreach (var url in crlUrls) { Console.WriteLine($"CRL URL: {url}"); } // Brza provjera bool hasCdp = certificate.HasCrlDistributionPoints(); ---- ===== Čitanje OCSP URL-ova ===== IReadOnlyList ocspUrls = certificate.GetOcspUrls(); foreach (var url in ocspUrls) { Console.WriteLine($"OCSP Responder: {url}"); } // Brza provjera bool hasOcsp = certificate.HasOcspUrls(); ---- ===== RevocationResult Klasa ===== ^ Svojstvo ^ Tip ^ Opis ^ | ''IsRevoked'' | bool | Certifikat je opozvan | | ''RevocationDate'' | DateTimeOffset? | Vrijeme opoziva | | ''Reason'' | CrlReason? | Razlog opoziva | | ''CrlVerified'' | bool | CRL potpis je verificiran | | ''ErrorMessage'' | string? | Poruka o grešci (ako provjera nije uspjela) | | ''Success'' | bool | Provjera je bila uspješna | ---- ===== CRL predmemorija ===== Za česte provjere s automatskim predmemoriranjem: using var cache = new CrlCache(defaultCacheDuration: TimeSpan.FromHours(1)); // Provjera s automatskim CRL predmemoriranjem RevocationResult result1 = await cache.CheckRevocationAsync(cert1, caCert); RevocationResult result2 = await cache.CheckRevocationAsync(cert2, caCert); // CRL iz predmemorije // Brisanje predmemorije cache.Clear(); **S vlastitim HttpClientom:** using var httpClient = new HttpClient(); using var cache = new CrlCache(httpClient, TimeSpan.FromMinutes(30)); // Provjera više certifikata foreach (var cert in certificates) { var result = await cache.CheckRevocationAsync(cert, caCert, CryptoMode.Hybrid); // ... } ---- ===== Integracija s X509Chain ===== Za potpunu validaciju lanca s CRL provjerom: using var chain = new X509Chain(); chain.ChainPolicy.RevocationMode = X509RevocationMode.Online; chain.ChainPolicy.RevocationFlag = X509RevocationFlag.EntireChain; bool valid = chain.Build(certificate, CryptoMode.Hybrid); if (!valid) { foreach (var status in chain.ChainStatus) { if (status.Status == X509ChainStatusFlags.Revoked) { Console.WriteLine("Certifikat u lancu je opozvan"); } } } ---- ===== Offline provjera ===== Za sustave bez mrežnog pristupa (air-gapped): // Prethodno preuzimanje i spremanje CRL-ova var crlFiles = new Dictionary { ["CN=Root CA"] = File.ReadAllBytes("root.crl"), ["CN=Issuing CA"] = File.ReadAllBytes("issuing.crl") }; // Offline provjera RevocationResult result = certificate.IsRevoked(crlFiles["CN=Issuing CA"], caCert); ---- ===== Najbolje prakse ===== * **Aktivirati CRL predmemoriranje:** Koristiti ''CrlCache'' za ponovljene provjere * **Postaviti timeout:** Konfigurirati HttpClient timeout za mrežne operacije * **Implementirati fallback:** Provjeriti OCSP ako CRL nije dostupan * **Offline kopije:** Održavati lokalne CRL kopije za kritične sustave ---- ===== Vidi također ===== * [[.:certificaterevocationlistextensions|CertificateRevocationListExtensions]] - Stvaranje CRL-a * [[.:x509chainextensions|X509ChainExtensions]] - Validacija lanca * [[hr:int:pqcrypt:konzepte:revocation|Koncept opoziva]] ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional// {{tag>crl revocation opoziv ocsp}}