Scenarij 4.4: Sigurnosna kopija certifikata i ključeva
Kategorija: Upravljanje certifikatima
Složenost: ⭐⭐⭐⭐ (Visoka)
Preduvjeti: Certifikati i ključevi dostupni
Procijenjeno vrijeme: 20-30 minuta
Opis
Ovaj scenarij opisuje sigurno sigurnosno kopiranje certifikata, privatnih ključeva i CA infrastrukture. Ispravan koncept sigurnosnog kopiranja kritičan je za:
- Oporavak od katastrofe - Obnova nakon kvara sustava
- Kontinuitet poslovanja - Nastavak rada
- Usklađenost - Obveze dokazivanja
- Key Escrow - Pohrana ključeva
KRITIČNO: Privatni ključevi su najvrjednija imovina! Sigurnosne kopije moraju biti:
- Šifrirane
- Pohranjene offline
- Zaštićene pristupom
- Redovito testirane
Tijek rada
flowchart TD
START[Pokretanje sigurnosne kopije] --> COLLECT[Prikupljanje podataka]
COLLECT --> ENCRYPT[Šifriranje]
ENCRYPT --> SIGN[Potpisivanje]
SIGN --> STORE1[Primarno spremište]
SIGN --> STORE2[Sekundarno spremište]
STORE1 --> VERIFY[Verifikacija]
STORE2 --> VERIFY
VERIFY --> LOG[Audit log]
style ENCRYPT fill:#fff3e0
style STORE1 fill:#e8f5e9
style STORE2 fill:#e8f5e9
Primjer koda (C#)
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using var ctx = PqCryptoContext.Initialize(); // Konfiguracija sigurnosne kopije var backupConfig = new BackupConfiguration { EncryptionPassword = "BackupPassword!Secure2024", OutputPath = "backup/", Timestamp = DateTime.UtcNow.ToString("yyyyMMdd-HHmmss"), IncludeChain = true }; // Učitavanje CA certifikata i ključa var caCert = ctx.LoadCertificate("root-ca.crt.pem"); var caKey = ctx.LoadPrivateKey("root-ca.key.pem", "CaPassword!"); // Kreiranje šifriranog PFX-a var pfxData = ctx.ExportToPfx( certificate: caCert, privateKey: caKey, chain: null, // Root nema lanac password: backupConfig.EncryptionPassword, friendlyName: $"Root-CA Backup {backupConfig.Timestamp}" ); // Datoteka sigurnosne kopije s metapodacima var backupPath = Path.Combine( backupConfig.OutputPath, $"root-ca-backup-{backupConfig.Timestamp}.pfx" ); Directory.CreateDirectory(backupConfig.OutputPath); File.WriteAllBytes(backupPath, pfxData); // Izračun kontrolne sume var checksum = ctx.ComputeSha256(pfxData); var checksumPath = backupPath + ".sha256"; File.WriteAllText(checksumPath, Convert.ToHexString(checksum)); // Spremanje metapodataka 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("Sigurnosna kopija kreirana:"); Console.WriteLine($" Datoteka: {backupPath}"); Console.WriteLine($" SHA256: {metadata.Checksum}"); Console.WriteLine($" Veličina: {new FileInfo(backupPath).Length:N0} bajtova");
Potpuna sigurnosna 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. Root-CA BackupCertificateAndKey(ctx, caDirectory, "root-ca", backupDir, backupPassword); // 2. Svi Intermediate-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. Kreiranje manifesta CreateBackupManifest(backupDir, timestamp); Console.WriteLine($"Potpuna CA sigurnosna kopija kreirana: {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 u čistom tekstu (PEM) var certBackup = Path.Combine(backupDir, "certs", $"{name}.crt.pem"); Directory.CreateDirectory(Path.GetDirectoryName(certBackup)!); cert.ToPemFile(certBackup); // Ključ šifrirano (ako postoji) if (File.Exists(keyPath)) { // Šifriranje ključa novom lozinkom var key = ctx.LoadPrivateKey(keyPath, "OriginalPassword!"); // Prilagoditi! 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 })); } }
Verifikacija sigurnosne kopije
public bool VerifyBackup(string backupPath, string password) { using var ctx = PqCryptoContext.Initialize(); // 1. Verifikacija kontrolne sume var expectedChecksum = File.ReadAllText(backupPath + ".sha256"); var actualData = File.ReadAllBytes(backupPath); var actualChecksum = Convert.ToHexString(ctx.ComputeSha256(actualData)); if (expectedChecksum != actualChecksum) { Console.WriteLine("GREŠKA: Kontrolna suma ne odgovara!"); return false; } // 2. Učitavanje PFX-a (testira lozinku i integritet) try { var (cert, key) = ctx.ImportFromPfx(actualData, password); Console.WriteLine($"Sigurnosna kopija OK: {cert.Subject}"); Console.WriteLine($" Vrijedi do: {cert.NotAfter:yyyy-MM-dd}"); Console.WriteLine($" Ključ: {(key != null ? "Prisutan" : "Nedostaje")}"); return true; } catch (CryptographicException ex) { Console.WriteLine($"GREŠKA: {ex.Message}"); return false; } }
Zahtjevi za sigurnosne kopije po industrijama
| Industrija | Propis | Učestalost kopiranja | Čuvanje | Posebnost |
|---|---|---|---|---|
| Financijski sektor | MaRisk | Dnevno | 10 godina | Geo-redundancija obvezna |
| Zdravstvo | GDPR | Dnevno | 30 godina | Air-Gap spremište |
| Energetika | KRITIS-VO | Tjedno | 10 godina | Offline mediji |
| Automobilska | UNECE R155 | Mjesečno | Životni vijek vozila | OTA-Recovery |
Strategija sigurnosnih kopija 3-2-1
Pravilo 3-2-1:
- 3 kopije podataka
- 2 različite vrste medija
- 1 kopija izvan lokacije
| Kopija | Medij | Lokacija | Svrha |
| ——– | ——- | ———- | ——- |
| 1 | Server Storage | Podatkovni centar | Operativno |
| 2 | Tape/NAS | Zgrada B | Oporavak od katastrofe |
| 3 | Cloud (šifrirano) | Druga lokacija | Geo-redundancija |
Povezani scenariji
| Odnos | Scenarij | Opis |
|---|---|---|
| Sljedeći korak | 4.3 Arhiviranje | Dugoročno čuvanje |
| Povezano | 11.2 Pohrana ključeva | Key Storage |
| Povezano | 12.2 PFX izvoz | Format izvoza |
« ← 4.3 Arhiviranje | ↑ Pregled upravljanja | → Svi scenariji »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: 30.01.2026. u 07:27