Scenarij 4.4: Varnostna kopija certifikatov in ključev

Kategorija: Upravljanje certifikatov
Kompleksnost: Visoka
Predpogoji: Obstoječi certifikati in ključi
Ocenjeni čas: 20-30 minut


Opis

Ta scenarij opisuje varno varnostno kopiranje certifikatov, zasebnih ključev in CA infrastrukture. Pravilna strategija varnostnih kopij je kritična za:

  • Obnovo po katastrofi - Obnovitev po okvari sistema
  • Neprekinjeno poslovanje - Nadaljevanje delovanja
  • Skladnost - Obveznosti dokazovanja
  • Depozit ključev - Hramba ključev

KRITIČNO: Zasebni ključi so najdragocenejša sredstva! Varnostne kopije morajo biti:

  • Šifrirane
  • Shranjene brez povezave
  • Zaščitene pred dostopom
  • Redno testirane

Potek dela

flowchart TD START[Zagon varnostne kopije] --> COLLECT[Zbiranje podatkov] COLLECT --> ENCRYPT[Šifriranje] ENCRYPT --> SIGN[Podpisovanje] SIGN --> STORE1[Primarna shramba] SIGN --> STORE2[Sekundarna shramba] STORE1 --> VERIFY[Preverjanje] STORE2 --> VERIFY VERIFY --> LOG[Revizijski dnevnik] style ENCRYPT fill:#fff3e0 style STORE1 fill:#e8f5e9 style STORE2 fill:#e8f5e9


Primer kode (C#)

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
 
using var ctx = PqCryptoContext.Initialize();
 
// Konfiguracija varnostne kopije
var backupConfig = new BackupConfiguration
{
    EncryptionPassword = "BackupPassword!Secure2024",
    OutputPath = "backup/",
    Timestamp = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss"),
    IncludeChain = true
};
 
// Nalaganje CA certifikata in ključa
var caCert = ctx.LoadCertificate("root-ca.crt.pem");
var caKey = ctx.LoadPrivateKey("root-ca.key.pem", "CaPassword!");
 
// Ustvarjanje šifriranega PFX
var pfxData = ctx.ExportToPfx(
    certificate: caCert,
    privateKey: caKey,
    chain: null,  // Root nima verige
    password: backupConfig.EncryptionPassword,
    friendlyName: $"Root-CA Backup {backupConfig.Timestamp}"
);
 
// Datoteka varnostne kopije z metapodatki
var backupPath = Path.Combine(
    backupConfig.OutputPath,
    $"root-ca-backup-{backupConfig.Timestamp}.pfx"
);
 
Directory.CreateDirectory(backupConfig.OutputPath);
File.WriteAllBytes(backupPath, pfxData);
 
// Izračun kontrolne vsote
var checksum = ctx.ComputeSha256(pfxData);
var checksumPath = backupPath + ".sha256";
File.WriteAllText(checksumPath, Convert.ToHexString(checksum));
 
// Shranjevanje metapodatkov
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("Varnostna kopija ustvarjena:");
Console.WriteLine($"  Datoteka: {backupPath}");
Console.WriteLine($"  SHA256: {metadata.Checksum}");
Console.WriteLine($"  Velikost: {new FileInfo(backupPath).Length:N0} bajtov");

Popolna varnostna kopija CA

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. Korenski CA
        BackupCertificateAndKey(ctx, caDirectory, "root-ca", backupDir, backupPassword);
 
        // 2. Vsi vmesni CA
        foreach (var intCaDir in Directory.GetDirectories(caDirectory, "intermediate-*"))
        {
            var name = Path.GetFileName(intCaDir);
            BackupCertificateAndKey(ctx, intCaDir, name, backupDir, backupPassword);
        }
 
        // 3. CRL datoteke
        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. Konfiguracijske datoteke
        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. Ustvarjanje manifesta
        CreateBackupManifest(backupDir, timestamp);
 
        Console.WriteLine($"Popolna varnostna kopija CA ustvarjena: {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);
 
        // Certifikat v čisti obliki (PEM)
        var certBackup = Path.Combine(backupDir, "certs", $"{name}.crt.pem");
        Directory.CreateDirectory(Path.GetDirectoryName(certBackup)!);
        cert.ToPemFile(certBackup);
 
        // Ključ šifriran (če obstaja)
        if (File.Exists(keyPath))
        {
            // Šifriranje ključa z novim geslom
            var key = ctx.LoadPrivateKey(keyPath, "OriginalPassword!");  // Prilagodi!
            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
        }));
    }
}

Preverjanje varnostne kopije

public bool VerifyBackup(string backupPath, string password)
{
    using var ctx = PqCryptoContext.Initialize();
 
    // 1. Preverjanje kontrolne vsote
    var expectedChecksum = File.ReadAllText(backupPath + ".sha256");
    var actualData = File.ReadAllBytes(backupPath);
    var actualChecksum = Convert.ToHexString(ctx.ComputeSha256(actualData));
 
    if (expectedChecksum != actualChecksum)
    {
        Console.WriteLine("NAPAKA: Kontrolna vsota se ne ujema!");
        return false;
    }
 
    // 2. Nalaganje PFX (preverja geslo in celovitost)
    try
    {
        var (cert, key) = ctx.ImportFromPfx(actualData, password);
        Console.WriteLine($"Varnostna kopija OK: {cert.Subject}");
        Console.WriteLine($"  Veljavno do: {cert.NotAfter:yyyy-MM-dd}");
        Console.WriteLine($"  Ključ: {(key != null ? "Prisoten" : "Manjka")}");
        return true;
    }
    catch (CryptographicException ex)
    {
        Console.WriteLine($"NAPAKA: {ex.Message}");
        return false;
    }
}

Panožne zahteve za varnostne kopije

Panoga Predpis Pogostost kopij Hramba Posebnost
Finančni sektor MaRisk Dnevno 10 let Obvezna georedundanca
Zdravstvo GDPR Dnevno 30 let Air-Gap shramba
Energetika KRITIS-VO Tedensko 10 let Mediji brez povezave
Avtomobilska UNECE R155 Mesečno Življenjska doba vozila OTA obnovitev

Strategija varnostnih kopij 3-2-1

Pravilo 3-2-1:

  • 3 kopije podatkov
  • 2 različna tipa medijev
  • 1 kopija na drugi lokaciji
Kopija Medij Lokacija Namen
——–——-———-——-
1 Strežniška shramba Podatkovni center Operativno
2 Trak/NAS Stavba B Obnova po katastrofi
3 Oblak (šifrirano) Druga lokacija Georedundanca

Povezani scenariji

Povezava Scenarij Opis
Naslednji korak 4.3 Arhiviranje Dolgoročna hramba
Povezano 11.2 Hramba ključev Shranjevanje ključev
Povezano 12.2 PFX izvoz Oblika izvoza

« ← 4.3 Arhiviranje | ↑ Pregled upravljanja | → Vsi scenariji »


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

Zuletzt geändert: dne 30.01.2026 ob 07:45