Szenario 4.4: Zertifikat- und Schlüssel-Backup

Kategorie: Zertifikate verwalten
Komplexität: ⭐⭐⭐⭐ (Hoch)
Voraussetzungen: Zertifikate und Schlüssel vorhanden
Geschätzte Zeit: 20-30 Minuten


Beschreibung

Dieses Szenario beschreibt das sichere Backup von Zertifikaten, privaten Schlüsseln und CA-Infrastruktur. Ein korrektes Backup-Konzept ist kritisch für:

  • Disaster Recovery - Wiederherstellung nach Systemausfall
  • Business Continuity - Betriebsfortführung
  • Compliance - Nachweispflichten
  • Key Escrow - Schlüsselhinterlegung

KRITISCH: Private Schlüssel sind das wertvollste Gut! Backups müssen:

  • Verschlüsselt sein
  • Offline gelagert werden
  • Zugriffsgeschützt sein
  • Regelmäßig getestet werden

Workflow

flowchart TD START[Backup initiieren] --> COLLECT[Daten sammeln] COLLECT --> ENCRYPT[Verschlüsseln] ENCRYPT --> SIGN[Signieren] SIGN --> STORE1[Primär-Storage] SIGN --> STORE2[Sekundär-Storage] STORE1 --> VERIFY[Verifizieren] STORE2 --> VERIFY VERIFY --> LOG[Audit-Log] style ENCRYPT fill:#fff3e0 style STORE1 fill:#e8f5e9 style STORE2 fill:#e8f5e9


Code-Beispiel (C#)

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
 
using var ctx = PqCryptoContext.Initialize();
 
// Backup-Konfiguration
var backupConfig = new BackupConfiguration
{
    EncryptionPassword = "BackupPassword!Secure2024",
    OutputPath = "backup/",
    Timestamp = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss"),
    IncludeChain = true
};
 
// CA-Zertifikat und Schlüssel laden
var caCert = ctx.LoadCertificate("root-ca.crt.pem");
var caKey = ctx.LoadPrivateKey("root-ca.key.pem", "CaPassword!");
 
// Verschlüsseltes PFX erstellen
var pfxData = ctx.ExportToPfx(
    certificate: caCert,
    privateKey: caKey,
    chain: null,  // Root hat keine Chain
    password: backupConfig.EncryptionPassword,
    friendlyName: $"Root-CA Backup {backupConfig.Timestamp}"
);
 
// Backup-Datei mit Metadaten
var backupPath = Path.Combine(
    backupConfig.OutputPath,
    $"root-ca-backup-{backupConfig.Timestamp}.pfx"
);
 
Directory.CreateDirectory(backupConfig.OutputPath);
File.WriteAllBytes(backupPath, pfxData);
 
// Prüfsumme berechnen
var checksum = ctx.ComputeSha256(pfxData);
var checksumPath = backupPath + ".sha256";
File.WriteAllText(checksumPath, Convert.ToHexString(checksum));
 
// Metadaten speichern
var metadata = new BackupMetadata
{
    BackupDate = DateTime.UtcNow,
    Subject = caCert.Subject,
    SerialNumber = caCert.SerialNumber,
    NotAfter = caCert.NotAfter,
    Checksum = Convert.ToHexString(checksum),
    Algorithm = caCert.PublicKey.Oid.FriendlyName
};
 
var metadataPath = backupPath + ".meta.json";
File.WriteAllText(metadataPath, JsonSerializer.Serialize(metadata, new JsonSerializerOptions
{
    WriteIndented = true
}));
 
Console.WriteLine("Backup erstellt:");
Console.WriteLine($"  Datei: {backupPath}");
Console.WriteLine($"  SHA256: {metadata.Checksum}");
Console.WriteLine($"  Größe: {new FileInfo(backupPath).Length:N0} Bytes");

Vollständiges CA-Backup

public class CaBackupManager
{
    public void CreateFullBackup(string caDirectory, string backupPassword, string outputPath)
    {
        var timestamp = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss");
        var backupDir = Path.Combine(outputPath, $"ca-backup-{timestamp}");
        Directory.CreateDirectory(backupDir);
 
        using var ctx = PqCryptoContext.Initialize();
 
        // 1. Root-CA
        BackupCertificateAndKey(ctx, caDirectory, "root-ca", backupDir, backupPassword);
 
        // 2. Alle Intermediate-CAs
        foreach (var intCaDir in Directory.GetDirectories(caDirectory, "intermediate-*"))
        {
            var name = Path.GetFileName(intCaDir);
            BackupCertificateAndKey(ctx, intCaDir, name, backupDir, backupPassword);
        }
 
        // 3. CRL-Dateien
        var crlDir = Path.Combine(backupDir, "crls");
        Directory.CreateDirectory(crlDir);
        foreach (var crl in Directory.GetFiles(caDirectory, "*.crl", SearchOption.AllDirectories))
        {
            File.Copy(crl, Path.Combine(crlDir, Path.GetFileName(crl)));
        }
 
        // 4. Konfigurationsdateien
        var configDir = Path.Combine(backupDir, "config");
        Directory.CreateDirectory(configDir);
        foreach (var config in Directory.GetFiles(caDirectory, "*.json"))
        {
            File.Copy(config, Path.Combine(configDir, Path.GetFileName(config)));
        }
 
        // 5. Manifest erstellen
        CreateBackupManifest(backupDir, timestamp);
 
        Console.WriteLine($"Vollständiges CA-Backup erstellt: {backupDir}");
    }
 
    private void BackupCertificateAndKey(
        PqCryptoContext ctx,
        string sourceDir,
        string name,
        string backupDir,
        string password)
    {
        var certPath = Path.Combine(sourceDir, $"{name}.crt.pem");
        var keyPath = Path.Combine(sourceDir, $"{name}.key.pem");
 
        if (!File.Exists(certPath)) return;
 
        var cert = ctx.LoadCertificate(certPath);
 
        // Zertifikat im Klartext (PEM)
        var certBackup = Path.Combine(backupDir, "certs", $"{name}.crt.pem");
        Directory.CreateDirectory(Path.GetDirectoryName(certBackup)!);
        cert.ToPemFile(certBackup);
 
        // Schlüssel verschlüsselt (falls vorhanden)
        if (File.Exists(keyPath))
        {
            // Schlüssel mit neuem Passwort verschlüsseln
            var key = ctx.LoadPrivateKey(keyPath, "OriginalPassword!");  // Anpassen!
            var keyBackup = Path.Combine(backupDir, "keys", $"{name}.key.pem.enc");
            Directory.CreateDirectory(Path.GetDirectoryName(keyBackup)!);
            key.ToEncryptedPemFile(keyBackup, password);
        }
    }
 
    private void CreateBackupManifest(string backupDir, string timestamp)
    {
        var manifest = new
        {
            Version = "1.0",
            Timestamp = timestamp,
            CreatedAt = DateTime.UtcNow,
            Contents = new
            {
                Certificates = Directory.GetFiles(Path.Combine(backupDir, "certs"), "*.pem").Length,
                Keys = Directory.GetFiles(Path.Combine(backupDir, "keys"), "*.enc").Length,
                CRLs = Directory.GetFiles(Path.Combine(backupDir, "crls"), "*.crl").Length,
                Configs = Directory.GetFiles(Path.Combine(backupDir, "config"), "*.json").Length
            }
        };
 
        var manifestPath = Path.Combine(backupDir, "MANIFEST.json");
        File.WriteAllText(manifestPath, JsonSerializer.Serialize(manifest, new JsonSerializerOptions
        {
            WriteIndented = true
        }));
    }
}

Backup-Verifizierung

public bool VerifyBackup(string backupPath, string password)
{
    using var ctx = PqCryptoContext.Initialize();
 
    // 1. Prüfsumme verifizieren
    var expectedChecksum = File.ReadAllText(backupPath + ".sha256");
    var actualData = File.ReadAllBytes(backupPath);
    var actualChecksum = Convert.ToHexString(ctx.ComputeSha256(actualData));
 
    if (expectedChecksum != actualChecksum)
    {
        Console.WriteLine("FEHLER: Prüfsumme stimmt nicht!");
        return false;
    }
 
    // 2. PFX laden (testet Passwort und Integrität)
    try
    {
        var (cert, key) = ctx.ImportFromPfx(actualData, password);
        Console.WriteLine($"Backup OK: {cert.Subject}");
        Console.WriteLine($"  Gültig bis: {cert.NotAfter:yyyy-MM-dd}");
        Console.WriteLine($"  Schlüssel: {(key != null ? "Vorhanden" : "Fehlt")}");
        return true;
    }
    catch (CryptographicException ex)
    {
        Console.WriteLine($"FEHLER: {ex.Message}");
        return false;
    }
}

Branchenspezifische Backup-Anforderungen

Branche Vorschrift Backup-Frequenz Aufbewahrung Besonderheit
Finanzsektor MaRisk Täglich 10 Jahre Georedundanz Pflicht
Healthcare DSGVO Täglich 30 Jahre Air-Gap Storage
Energie KRITIS-VO Wöchentlich 10 Jahre Offline-Medien
Automotive UNECE R155 Monatlich Fahrzeug-Lifetime OTA-Recovery

Backup-Strategie 3-2-1

3-2-1 Regel:

  • 3 Kopien der Daten
  • 2 verschiedene Medientypen
  • 1 Kopie Off-Site
Kopie Medium Ort Zweck
——-——–—–——-
1 Server-Storage Rechenzentrum Operativ
2 Tape/NAS Gebäude B Disaster Recovery
3 Cloud (verschlüsselt) Anderer Standort Georedundanz

Verwandte Szenarien

Beziehung Szenario Beschreibung
Nächster Schritt 4.3 Archivierung Langzeit-Aufbewahrung
Verwandt 11.2 Schlüsselspeicherung Key Storage
Verwandt 12.2 PFX-Export Export-Format

« ← 4.3 Archivierung | ↑ Verwaltung-Übersicht | → Alle Szenarien »


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

Zuletzt geändert: den 29.01.2026 um 15:13