Scenarij 6.1: Ustvarjanje CRL

Kategorija: Preklic (Revocation)
Kompleksnost: Srednja
Predpogoji: Certifikat in ključ CA
Ocenjeni čas: 15-20 minut


Opis

Ta scenarij opisuje ustvarjanje seznama preklicanih certifikatov (CRL) po RFC 5280. CRL so podpisani seznami preklicanih certifikatov, ki jih objavljajo CA.

Polja CRL:


Potek dela

flowchart LR REV[Preklicani certifikati] --> BUILD[CRL Builder] BUILD --> SIGN[Podpis s CA] SIGN --> PUBLISH[Objava] PUBLISH --> CDP[Posodobitev CDP URL] style SIGN fill:#e8f5e9


Primer kode (C#)

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Security.Cryptography.X509Certificates;
 
using var ctx = PqCryptoContext.Initialize();
 
// Nalaganje CA
var caCert = ctx.LoadCertificate("intermediate-ca.crt.pem");
var caKey = ctx.LoadPrivateKey("intermediate-ca.key.pem", "CaPassword!");
 
// Ustvarjanje CRL Builder
var crlBuilder = new CertificateRevocationListBuilder();
 
// Dodajanje preklicanih certifikatov
crlBuilder.AddEntry(
    serialNumber: new byte[] { 0x01, 0x02, 0x03 },
    revocationTime: new DateTimeOffset(2024, 6, 15, 10, 30, 0, TimeSpan.Zero),
    reason: X509RevocationReason.KeyCompromise
);
 
crlBuilder.AddEntry(
    serialNumber: new byte[] { 0x01, 0x02, 0x04 },
    revocationTime: DateTimeOffset.UtcNow.AddDays(-7),
    reason: X509RevocationReason.CessationOfOperation
);
 
// Generiranje CRL
byte[] crlBytes = crlBuilder.Build(
    issuerCertificate: caCert,
    crlNumber: BigInteger.Parse("1000"),
    nextUpdate: DateTimeOffset.UtcNow.AddDays(7),
    hashAlgorithm: HashAlgorithmName.SHA256,
    rsaSignaturePadding: null,  // Za PQ ni relevantno
    mode: CryptoMode.Hybrid
);
 
// Shranjevanje CRL
File.WriteAllBytes("intermediate-ca.crl", crlBytes);
 
// Pretvorba CRL v PEM
var crlPem = ctx.ToPem(crlBytes, "X509 CRL");
File.WriteAllText("intermediate-ca.crl.pem", crlPem);
 
Console.WriteLine("CRL ustvarjen:");
Console.WriteLine($"  Vnosi: {crlBuilder.Entries.Count}");
Console.WriteLine($"  CRL Number: 1000");
Console.WriteLine($"  Next Update: {DateTimeOffset.UtcNow.AddDays(7):yyyy-MM-dd}");

Posodabljanje CRL iz obstoječega CRL

public class CrlUpdater
{
    public byte[] UpdateCrl(
        byte[] existingCrl,
        X509Certificate2 caCert,
        AsymmetricAlgorithm caKey,
        IEnumerable<CrlEntry>? newEntries = null)
    {
        using var ctx = PqCryptoContext.Initialize();
 
        // Razčlenjevanje obstoječega CRL
        var parsedCrl = ctx.ParseCrl(existingCrl);
 
        // Nov Builder z obstoječimi vnosi
        var builder = new CertificateRevocationListBuilder();
 
        foreach (var entry in parsedCrl.Entries)
        {
            builder.AddEntry(entry.SerialNumber, entry.RevocationTime, entry.Reason);
        }
 
        // Dodajanje novih vnosov
        if (newEntries != null)
        {
            foreach (var entry in newEntries)
            {
                builder.AddEntry(entry.SerialNumber, entry.RevocationTime, entry.Reason);
            }
        }
 
        // Nova CRL-številka (povečana)
        var newCrlNumber = parsedCrl.CrlNumber + 1;
 
        // Ustvarjanje novega CRL
        return builder.Build(
            issuerCertificate: caCert,
            crlNumber: newCrlNumber,
            nextUpdate: DateTimeOffset.UtcNow.AddDays(7),
            hashAlgorithm: HashAlgorithmName.SHA256,
            mode: CryptoMode.Hybrid
        );
    }
}

CRL Extensions

// CRL z razširitvami
var crlBuilder = new CertificateRevocationListBuilder();
 
// CRL Extensions
crlBuilder.AddExtension(
    oid: "2.5.29.20",  // CRL Number
    critical: false,
    value: BuildCrlNumberExtension(1001)
);
 
crlBuilder.AddExtension(
    oid: "2.5.29.35",  // Authority Key Identifier
    critical: false,
    value: BuildAkiExtension(caCert)
);
 
crlBuilder.AddExtension(
    oid: "2.5.29.28",  // Issuing Distribution Point
    critical: true,
    value: BuildIdpExtension(
        distributionPoint: "http://crl.example.com/intermediate.crl",
        onlyContainUserCerts: true
    )
);
 
// Entry Extensions (za vsak preklicanem certifikat)
crlBuilder.AddEntry(
    serialNumber: revokedSerial,
    revocationTime: DateTimeOffset.UtcNow,
    reason: X509RevocationReason.KeyCompromise,
    extensions: new X509ExtensionCollection
    {
        // Invalidity Date (kdaj je bil dejansko ogrožen)
        BuildInvalidityDateExtension(compromiseDate),
        // Certificate Issuer (če je Indirect CRL)
        BuildCertificateIssuerExtension(certIssuerDn)
    }
);

Razlogi za preklic (RFC 5280)

Koda Razlog Opis
0 unspecified Brez specifičnega razloga
1 keyCompromise Ključ ogrožen
2 cACompromise CA ogrožena
3 affiliationChanged Pripadnost spremenjena
4 superseded Zamenjano z novim certifikatom
5 cessationOfOperation Delovanje ustavljeno
6 certificateHold Začasno blokirano
8 removeFromCRL Odstranitev iz CRL (odprava blokade)
9 privilegeWithdrawn Pooblastilo odvzeto
10 aACompromise Atributna agencija ogrožena

Konfiguracija CRL Distribution Point

// Izdaja certifikata s CDP
var cert = ctx.IssueCertificate(
    csr,
    issuerCert: caCert,
    issuerKey: caKey,
    extensions: new ExtBuilder()
        .CrlDistributionPoint(
            uri: "http://crl.example.com/intermediate.crl",
            ldapUri: "ldap://ldap.example.com/cn=Intermediate-CA,o=Example,c=DE?certificateRevocationList"
        )
        .Build()
);

Panožne zahteve za CRL

Panoga Maks. nextUpdate Format Distribucija
WebPKI 7 dni DER HTTP
Enterprise 24 ur DER/PEM HTTP, LDAP
Energetika/SCADA 30 dni DER Brez povezave
Zdravstvo 24 ur DER HTTP

Najboljša praksa: Posodobite CRL pred nextUpdate (50-75% obdobja veljavnosti).


Povezani scenariji

Povezava Scenarij Opis
Alternativa 6.2 OCSP strežnik Sprotno preverjanje
Razširitev 6.3 Delta-CRL Inkrementalne posodobitve
Predpogoj 6.4 Preklic certifikata Postopek preklica

« ← Pregled preklica | ↑ Scenariji | 6.2 OCSP strežnik → »


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