Scenario 6.3: Delta-CRL

Categoria: Revoca (Revocation)
Complessità: Alta
Prerequisiti: CRL base presente
Tempo stimato: 20-30 minuti


Descrizione

Questo scenario descrive la creazione di Delta-CRL (RFC 5280 §5.2.4). Le Delta-CRL contengono solo le modifiche dall'ultima CRL base e consentono aggiornamenti più efficienti.

Vantaggi:

  • Dimensione download ridotta
  • Aggiornamenti più frequenti possibili
  • Banda ridotta
  • Propagazione più rapida

Svantaggi:

  • Implementazione più complessa
  • CRL base deve essere disponibile
  • Infrastruttura aggiuntiva

Workflow

flowchart TD BASE[CRL Base] --> DELTA1[Delta-CRL 1] DELTA1 --> DELTA2[Delta-CRL 2] DELTA2 --> DELTA3[Delta-CRL 3] DELTA3 --> NEW_BASE[Nuova CRL Base] NEW_BASE --> DELTA4[Delta-CRL 4] CLIENT[Client] --> |Download| BASE CLIENT --> |Aggiornamenti| DELTA1 CLIENT --> |Aggiornamenti| 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


Esempio codice: Creare Delta-CRL

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Numerics;
 
using var ctx = PqCryptoContext.Initialize();
 
// CA laden
var caCert = ctx.LoadCertificate("intermediate-ca.crt.pem");
var caKey = ctx.LoadPrivateKey("intermediate-ca.key.pem", "CaPassword!");
 
// Basis-CRL laden
var baseCrl = ctx.ParseCrl(File.ReadAllBytes("intermediate-ca-base.crl"));
var baseCrlNumber = baseCrl.CrlNumber;
 
// Delta-CRL Builder
var deltaCrlBuilder = new CertificateRevocationListBuilder();
 
// Nur NEUE Widerrufe seit Basis-CRL hinzufügen
var newRevocations = GetRevocationsSince(baseCrl.ThisUpdate);
foreach (var rev in newRevocations)
{
    deltaCrlBuilder.AddEntry(
        rev.SerialNumber,
        rev.RevocationTime,
        rev.Reason
    );
}
 
// Optional: Zertifikate aus "Hold" zurücknehmen
var removedFromHold = GetRemovedFromHold(baseCrl.ThisUpdate);
foreach (var serial in removedFromHold)
{
    deltaCrlBuilder.AddEntry(
        serial,
        DateTimeOffset.UtcNow,
        X509RevocationReason.RemoveFromCrl  // Code 8
    );
}
 
// Delta-CRL Extensions
deltaCrlBuilder.AddExtension(
    oid: "2.5.29.27",  // Delta CRL Indicator
    critical: true,
    value: EncodeDeltaCrlIndicator(baseCrlNumber)
);
 
// Delta-CRL generieren
byte[] deltaCrlBytes = deltaCrlBuilder.Build(
    issuerCertificate: caCert,
    crlNumber: baseCrlNumber + 10,  // Delta-Nummern zwischen Basis-Nummern
    nextUpdate: DateTimeOffset.UtcNow.AddHours(4),  // Häufiger als Basis
    hashAlgorithm: HashAlgorithmName.SHA256,
    mode: CryptoMode.Hybrid
);
 
File.WriteAllBytes("intermediate-ca-delta.crl", deltaCrlBytes);
 
Console.WriteLine($"Delta-CRL erstellt:");
Console.WriteLine($"  Basis-CRL Number: {baseCrlNumber}");
Console.WriteLine($"  Delta-CRL Number: {baseCrlNumber + 10}");
Console.WriteLine($"  Neue Einträge: {newRevocations.Count}");
Console.WriteLine($"  Removed from Hold: {removedFromHold.Count}");

Delta-CRL Indicator Extension

private byte[] EncodeDeltaCrlIndicator(BigInteger baseCrlNumber)
{
    // Delta CRL Indicator ist einfach die Basis-CRL-Nummer als INTEGER
    var writer = new AsnWriter(AsnEncodingRules.DER);
    writer.WriteInteger(baseCrlNumber);
    return writer.Encode();
}

CRL Base con supporto Delta-CRL

// Basis-CRL muss auf Delta-CRLs verweisen
var baseCrlBuilder = new CertificateRevocationListBuilder();
 
// Alle widerrufenen Zertifikate hinzufügen
foreach (var rev in allRevocations)
{
    baseCrlBuilder.AddEntry(rev.SerialNumber, rev.RevocationTime, rev.Reason);
}
 
// Freshest CRL Extension (verweist auf 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),  // Längere Gültigkeit
    hashAlgorithm: HashAlgorithmName.SHA256,
    mode: CryptoMode.Hybrid
);
 
File.WriteAllBytes("intermediate-ca-base.crl", baseCrlBytes);

Elaborazione Delta-CRL lato client

public class DeltaCrlProcessor
{
    public CombinedRevocationList CombineCrls(
        byte[] baseCrlBytes,
        byte[] deltaCrlBytes,
        PqCryptoContext ctx)
    {
        var baseCrl = ctx.ParseCrl(baseCrlBytes);
        var deltaCrl = ctx.ParseCrl(deltaCrlBytes);
 
        // Prüfen ob Delta zur Basis passt
        var deltaIndicator = GetDeltaCrlIndicator(deltaCrl);
        if (deltaIndicator != baseCrl.CrlNumber)
        {
            throw new InvalidOperationException(
                $"Delta-CRL (Indicator: {deltaIndicator}) passt nicht zur Basis-CRL ({baseCrl.CrlNumber})"
            );
        }
 
        // Kombinierte Liste erstellen
        var combined = new CombinedRevocationList
        {
            BaseCrlNumber = baseCrl.CrlNumber,
            DeltaCrlNumber = deltaCrl.CrlNumber,
            ThisUpdate = deltaCrl.ThisUpdate,  // Delta ist aktueller
            NextUpdate = deltaCrl.NextUpdate,
            Entries = new Dictionary<string, RevocationEntry>()
        };
 
        // Basis-Einträge übernehmen
        foreach (var entry in baseCrl.Entries)
        {
            combined.Entries[entry.SerialNumber] = entry;
        }
 
        // Delta-Einträge anwenden
        foreach (var entry in deltaCrl.Entries)
        {
            if (entry.Reason == X509RevocationReason.RemoveFromCrl)
            {
                // Aus CRL entfernen (Hold aufgehoben)
                combined.Entries.Remove(entry.SerialNumber);
            }
            else
            {
                // Hinzufügen oder aktualisieren
                combined.Entries[entry.SerialNumber] = entry;
            }
        }
 
        return combined;
    }
 
    public bool IsRevoked(string serialNumber, CombinedRevocationList crl)
    {
        return crl.Entries.ContainsKey(serialNumber);
    }
}

Ciclo Delta-CRL automatizzato

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)
            {
                // Zeit für neue Basis-CRL
                await CreateBaseCrl();
                lastBaseCrl = DateTimeOffset.UtcNow;
                _currentBaseCrlNumber += 100;
                _currentDeltaNumber = 0;
            }
            else
            {
                // Delta-CRL erstellen
                await CreateDeltaCrl();
                _currentDeltaNumber++;
            }
 
            await Task.Delay(_deltaCrlInterval, cancellationToken);
        }
    }
 
    private async Task CreateBaseCrl()
    {
        Console.WriteLine($"Erstelle Basis-CRL #{_currentBaseCrlNumber}");
        // ... Basis-CRL Logik
    }
 
    private async Task CreateDeltaCrl()
    {
        var deltaCrlNumber = _currentBaseCrlNumber + _currentDeltaNumber;
        Console.WriteLine($"Erstelle Delta-CRL #{deltaCrlNumber} (Basis: {_currentBaseCrlNumber})");
        // ... Delta-CRL Logik
    }
}

Cicli Delta-CRL specifici per settore

Settore CRL Base Delta-CRL Raccomandazione
WebPKI 7 giorni 4 ore Opzionale, OCSP preferito
Enterprise 24 ore 1 ora Raccomandato
Settore finanziario 12 ore 15 minuti Obbligatorio
Energia/SCADA 7 giorni 24 ore Secondo connettività

Scenari correlati

Relazione Scenario Descrizione
Prerequisito 6.1 Creare CRL CRL Base
Alternativa 6.2 OCSP Responder Stato in tempo reale
Correlato 5.3 Revocation Check Verifica client

« ← 6.2 OCSP Responder | ↑ Panoramica revoca | 6.4 Revocare certificato → »


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

Zuletzt geändert: il 30/01/2026 alle 07:16