Scenarij 6.3: Delta-CRL

Kategorija: Opoziv (Revocation)
Složenost: ⭐⭐⭐⭐ (Visoka)
Preduvjeti: Bazni CRL dostupan
Procijenjeno vrijeme: 20-30 minuta


Opis

Ovaj scenarij opisuje kreiranje Delta-CRL-ova (RFC 5280 §5.2.4). Delta-CRL-ovi sadrže samo promjene od posljednjeg baznog CRL-a i omogućuju učinkovitija ažuriranja.

Prednosti:

Nedostaci:


Tijek rada

flowchart TD BASE[Bazni CRL] --> DELTA1[Delta-CRL 1] DELTA1 --> DELTA2[Delta-CRL 2] DELTA2 --> DELTA3[Delta-CRL 3] DELTA3 --> NEW_BASE[Novi bazni CRL] NEW_BASE --> DELTA4[Delta-CRL 4] CLIENT[Klijent] --> |Preuzimanje| BASE CLIENT --> |Ažuriranja| DELTA1 CLIENT --> |Ažuriranja| DELTA2 style BASE fill:#e3f2fd style NEW_BASE fill:#e3f2fd style DELTA1 fill:#fff3e0 style DELTA2 fill:#fff3e0 style DELTA3 fill:#fff3e0 style DELTA4 fill:#fff3e0


Primjer koda: Kreiranje Delta-CRL-a

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Numerics;
 
using var ctx = PqCryptoContext.Initialize();
 
// Učitavanje CA
var caCert = ctx.LoadCertificate("intermediate-ca.crt.pem");
var caKey = ctx.LoadPrivateKey("intermediate-ca.key.pem", "CaPassword!");
 
// Učitavanje baznog CRL-a
var baseCrl = ctx.ParseCrl(File.ReadAllBytes("intermediate-ca-base.crl"));
var baseCrlNumber = baseCrl.CrlNumber;
 
// Delta-CRL Builder
var deltaCrlBuilder = new CertificateRevocationListBuilder();
 
// Dodavanje samo NOVIH opoziva od baznog CRL-a
var newRevocations = GetRevocationsSince(baseCrl.ThisUpdate);
foreach (var rev in newRevocations)
{
    deltaCrlBuilder.AddEntry(
        rev.SerialNumber,
        rev.RevocationTime,
        rev.Reason
    );
}
 
// Opcionalno: vraćanje certifikata iz "Hold" stanja
var removedFromHold = GetRemovedFromHold(baseCrl.ThisUpdate);
foreach (var serial in removedFromHold)
{
    deltaCrlBuilder.AddEntry(
        serial,
        DateTimeOffset.UtcNow,
        X509RevocationReason.RemoveFromCrl  // Kod 8
    );
}
 
// Delta-CRL ekstenzije
deltaCrlBuilder.AddExtension(
    oid: "2.5.29.27",  // Delta CRL Indicator
    critical: true,
    value: EncodeDeltaCrlIndicator(baseCrlNumber)
);
 
// Generiranje Delta-CRL-a
byte[] deltaCrlBytes = deltaCrlBuilder.Build(
    issuerCertificate: caCert,
    crlNumber: baseCrlNumber + 10,  // Delta brojevi između baznih brojeva
    nextUpdate: DateTimeOffset.UtcNow.AddHours(4),  // Češće od baznog
    hashAlgorithm: HashAlgorithmName.SHA256,
    mode: CryptoMode.Hybrid
);
 
File.WriteAllBytes("intermediate-ca-delta.crl", deltaCrlBytes);
 
Console.WriteLine($"Delta-CRL kreiran:");
Console.WriteLine($"  Bazni CRL Number: {baseCrlNumber}");
Console.WriteLine($"  Delta-CRL Number: {baseCrlNumber + 10}");
Console.WriteLine($"  Novi unosi: {newRevocations.Count}");
Console.WriteLine($"  Uklonjeno iz Hold: {removedFromHold.Count}");

Delta CRL Indicator Extension

private byte[] EncodeDeltaCrlIndicator(BigInteger baseCrlNumber)
{
    // Delta CRL Indicator je jednostavno broj baznog CRL-a kao INTEGER
    var writer = new AsnWriter(AsnEncodingRules.DER);
    writer.WriteInteger(baseCrlNumber);
    return writer.Encode();
}

Bazni CRL s podrškom za Delta-CRL

// Bazni CRL mora referencirati Delta-CRL-ove
var baseCrlBuilder = new CertificateRevocationListBuilder();
 
// Dodavanje svih opozvanih certifikata
foreach (var rev in allRevocations)
{
    baseCrlBuilder.AddEntry(rev.SerialNumber, rev.RevocationTime, rev.Reason);
}
 
// Freshest CRL Extension (referencira Delta-CRL)
baseCrlBuilder.AddExtension(
    oid: "2.5.29.46",  // Freshest CRL (Delta CRL Distribution Point)
    critical: false,
    value: EncodeFreshestCrl("http://crl.example.com/intermediate-delta.crl")
);
 
byte[] baseCrlBytes = baseCrlBuilder.Build(
    issuerCertificate: caCert,
    crlNumber: BigInteger.Parse("1000"),
    nextUpdate: DateTimeOffset.UtcNow.AddDays(7),  // Dulja valjanost
    hashAlgorithm: HashAlgorithmName.SHA256,
    mode: CryptoMode.Hybrid
);
 
File.WriteAllBytes("intermediate-ca-base.crl", baseCrlBytes);

Obrada Delta-CRL-a na strani klijenta

public class DeltaCrlProcessor
{
    public CombinedRevocationList CombineCrls(
        byte[] baseCrlBytes,
        byte[] deltaCrlBytes,
        PqCryptoContext ctx)
    {
        var baseCrl = ctx.ParseCrl(baseCrlBytes);
        var deltaCrl = ctx.ParseCrl(deltaCrlBytes);
 
        // Provjera odgovara li Delta baznom
        var deltaIndicator = GetDeltaCrlIndicator(deltaCrl);
        if (deltaIndicator != baseCrl.CrlNumber)
        {
            throw new InvalidOperationException(
                $"Delta-CRL (Indicator: {deltaIndicator}) ne odgovara baznom CRL-u ({baseCrl.CrlNumber})"
            );
        }
 
        // Kreiranje kombinirane liste
        var combined = new CombinedRevocationList
        {
            BaseCrlNumber = baseCrl.CrlNumber,
            DeltaCrlNumber = deltaCrl.CrlNumber,
            ThisUpdate = deltaCrl.ThisUpdate,  // Delta je aktualniji
            NextUpdate = deltaCrl.NextUpdate,
            Entries = new Dictionary<string, RevocationEntry>()
        };
 
        // Preuzimanje baznih unosa
        foreach (var entry in baseCrl.Entries)
        {
            combined.Entries[entry.SerialNumber] = entry;
        }
 
        // Primjena Delta unosa
        foreach (var entry in deltaCrl.Entries)
        {
            if (entry.Reason == X509RevocationReason.RemoveFromCrl)
            {
                // Uklanjanje iz CRL-a (Hold ukinut)
                combined.Entries.Remove(entry.SerialNumber);
            }
            else
            {
                // Dodavanje ili ažuriranje
                combined.Entries[entry.SerialNumber] = entry;
            }
        }
 
        return combined;
    }
 
    public bool IsRevoked(string serialNumber, CombinedRevocationList crl)
    {
        return crl.Entries.ContainsKey(serialNumber);
    }
}

Automatizirani Delta-CRL ciklus

public class DeltaCrlScheduler
{
    private readonly TimeSpan _baseCrlInterval = TimeSpan.FromDays(7);
    private readonly TimeSpan _deltaCrlInterval = TimeSpan.FromHours(4);
    private BigInteger _currentBaseCrlNumber = 1000;
    private BigInteger _currentDeltaNumber = 0;
 
    public async Task RunScheduler(CancellationToken cancellationToken)
    {
        var lastBaseCrl = DateTimeOffset.UtcNow;
 
        while (!cancellationToken.IsCancellationRequested)
        {
            if (DateTimeOffset.UtcNow - lastBaseCrl >= _baseCrlInterval)
            {
                // Vrijeme za novi bazni CRL
                await CreateBaseCrl();
                lastBaseCrl = DateTimeOffset.UtcNow;
                _currentBaseCrlNumber += 100;
                _currentDeltaNumber = 0;
            }
            else
            {
                // Kreiranje Delta-CRL-a
                await CreateDeltaCrl();
                _currentDeltaNumber++;
            }
 
            await Task.Delay(_deltaCrlInterval, cancellationToken);
        }
    }
 
    private async Task CreateBaseCrl()
    {
        Console.WriteLine($"Kreiranje baznog CRL-a #{_currentBaseCrlNumber}");
        // ... Bazni CRL logika
    }
 
    private async Task CreateDeltaCrl()
    {
        var deltaCrlNumber = _currentBaseCrlNumber + _currentDeltaNumber;
        Console.WriteLine($"Kreiranje Delta-CRL-a #{deltaCrlNumber} (Bazni: {_currentBaseCrlNumber})");
        // ... Delta-CRL logika
    }
}

Ciklusi Delta-CRL-a po industrijama

Industrija Bazni CRL Delta-CRL Preporuka
WebPKI 7 dana 4 sata Opcionalno, preferira se OCSP
Enterprise 24 sata 1 sat Preporučeno
Financijski sektor 12 sati 15 minuta Obvezno
Energetika/SCADA 7 dana 24 sata Ovisno o povezanosti

Povezani scenariji

Odnos Scenarij Opis
Preduvjet 6.1 Kreiranje CRL-a Bazni CRL
Alternativa 6.2 OCSP Responder Status u stvarnom vremenu
Povezano 5.3 Provjera opoziva Provjera na klijentu

« ← 6.2 OCSP Responder | ↑ Pregled opoziva | 6.4 Opoziv certifikata → »


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