Scenarij 1.1: Ustvarjanje korenskega CA s PQ ključi

Kategorija: PKI infrastruktura
Kompleksnost: ⭐⭐⭐⭐ (Visoka)
Predpogoji: Brez (vstopna točka)
Predviden čas: 15-30 minut


Opis

Ta scenarij opisuje ustvarjanje samopodpisanega korenskega CA s postkvantnimi ključi. Korenski CA tvori sidro zaupanja (Trust Anchor) za celotno PKI hierarhijo in je varnostno najkritičnejši element infrastrukture.

Kaj se ustvari:

Primeri uporabe:


Diagram poteka

┌─────────────────────────────────────────────────────────────────┐
│                    USTVARJANJE KORENSKEGA CA                     │
└─────────────────────────────────────────────────────────────────┘

     ┌──────────────┐
     │ 1. Init      │
     │ Knjižnica    │
     └──────┬───────┘
            │
            ▼
     ┌──────────────┐
     │ 2. KeyPair   │ ──────► ML-DSA-65 (FIPS 204)
     │ generiranje  │         ~4KB javni ključ
     └──────┬───────┘         ~2KB zasebni ključ
            │
            ▼
     ┌──────────────┐
     │ 3. DN        │ ──────► CN=WvdS Root CA
     │ ustvarjanje  │         O=DATECpro GmbH
     └──────┬───────┘         C=SI
            │
            ▼
     ┌──────────────┐
     │ 4. Serial    │ ──────► 20 bajtov naključno (160 bit)
     │ generiranje  │
     └──────┬───────┘
            │
            ▼
     ┌──────────────┐
     │ 5. Veljavnost│ ──────► notBefore: zdaj
     │ določitev    │         notAfter: +20 let
     └──────┬───────┘
            │
            ▼
     ┌──────────────┐
     │ 6. Razširitve│ ──────► BasicConstraints: CA=true, pathLen=1
     │ nastavitev   │         KeyUsage: keyCertSign, cRLSign
     └──────┬───────┘         SKI: SHA-256(publicKey)
            │
            ▼
     ┌──────────────┐
     │ 7. Certifikat│ ──────► Subject = Issuer (samopodpisan)
     │ ustvarjanje  │         Podpis z ML-DSA-65
     └──────┬───────┘
            │
            ▼
     ┌──────────────┐
     │ 8. Izvoz     │ ──────► root-ca.crt.pem (certifikat)
     │ PEM          │         root-ca.key.pem (šifriran)
     └──────┬───────┘
            │
            ▼
     ┌──────────────┐
     │ 9. Čiščenje  │ ──────► Sprostitev ročajev
     │              │         Brisanje skrivnosti
     └──────────────┘

Primer kode

C# (.NET Wrapper)

using System;
using System.IO;
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
 
namespace RootCaExample
{
    class Program
    {
        static void Main(string[] args)
        {
            // Geslo za zasebni ključ (v produkciji: varno vnašanje!)
            string keyPassword = "MyStr0ng!RootCA#Password2024";
 
            // 1. Inicializacija konteksta
            using var context = PqCryptoContext.Initialize();
 
            // 2. Generiranje para ključev ML-DSA-65
            Console.WriteLine("Generiram par ključev ML-DSA-65...");
            using var keyPair = context.GenerateKeyPair(PqAlgorithm.MlDsa65);
 
            // Izvedba samopreizkusa
            if (!keyPair.SelfTest())
                throw new CryptographicException("Samopreizkus para ključev ni uspel!");
 
            Console.WriteLine($"  Javni ključ:  {keyPair.PublicKeySize} bajtov");
            Console.WriteLine($"  Zasebni ključ: {keyPair.PrivateKeySize} bajtov");
 
            // 3. Ustvarjanje Distinguished Name
            var subjectDn = new DistinguishedNameBuilder()
                .AddCommonName("WvdS Root CA")
                .AddOrganization("DATECpro GmbH")
                .AddOrganizationalUnit("PQ-Security")
                .AddCountry("SI")
                .AddLocality("Ljubljana")
                .Build();
 
            Console.WriteLine($"Subject DN: {subjectDn}");
 
            // 4. Obdobje veljavnosti (20 let za korenski CA)
            var validity = new CertificateValidity(
                notBefore: DateTime.UtcNow,
                notAfter: DateTime.UtcNow.AddYears(20)
            );
 
            // 5. Razširitve za korenski CA
            var extensions = new X509ExtensionsBuilder()
                // BasicConstraints: CA=true, največ 1 vmesna raven
                .AddBasicConstraints(isCa: true, pathLengthConstraint: 1, critical: true)
                // KeyUsage: samo podpisovanje certifikatov in CRL
                .AddKeyUsage(
                    KeyUsageFlags.KeyCertSign | KeyUsageFlags.CrlSign,
                    critical: true
                )
                // Subject Key Identifier za kasnejše sklicevanje AKI
                .AddSubjectKeyIdentifier(keyPair)
                .Build();
 
            // 6. Ustvarjanje korenskega certifikata (samopodpisan)
            Console.WriteLine("Ustvarjam samopodpisan korenski certifikat...");
            using var rootCert = context.CreateRootCertificate(
                keyPair: keyPair,
                subject: subjectDn,
                validity: validity,
                extensions: extensions
            );
 
            // 7. Izpis informacij o certifikatu
            Console.WriteLine("\n=== KORENSKI CA CERTIFIKAT ===");
            Console.WriteLine($"Subject:        {rootCert.Subject}");
            Console.WriteLine($"Issuer:         {rootCert.Issuer}");
            Console.WriteLine($"Serial:         {rootCert.SerialNumber}");
            Console.WriteLine($"Veljavno od:    {rootCert.NotBefore:yyyy-MM-dd HH:mm:ss} UTC");
            Console.WriteLine($"Veljavno do:    {rootCert.NotAfter:yyyy-MM-dd HH:mm:ss} UTC");
            Console.WriteLine($"Algoritem:      {rootCert.SignatureAlgorithm}");
            Console.WriteLine($"Prstni odtis:   {rootCert.Thumbprint}");
            Console.WriteLine($"Je CA:          {rootCert.IsCertificateAuthority}");
            Console.WriteLine($"Dolžina poti:   {rootCert.PathLengthConstraint}");
 
            // 8. Shranjevanje kot PEM datoteke
            string certPath = "root-ca.crt.pem";
            string keyPath = "root-ca.key.pem";
 
            // Certifikat (javni)
            File.WriteAllText(certPath, rootCert.ExportToPem());
            Console.WriteLine($"\nCertifikat shranjen: {certPath}");
 
            // Zasebni ključ (šifriran z Argon2id)
            File.WriteAllText(keyPath, keyPair.ExportToEncryptedPem(
                password: keyPassword,
                kdfAlgorithm: KeyDerivationAlgorithm.Argon2id
            ));
            Console.WriteLine($"Zasebni ključ shranjen: {keyPath} (šifriran)");
 
            // 9. Validacija: ponovna naložitev certifikata in preverjanje
            Console.WriteLine("\n=== VALIDACIJA ===");
            using var loadedCert = context.LoadCertificateFromPem(File.ReadAllText(certPath));
            using var loadedKey = context.LoadKeyPairFromEncryptedPem(
                File.ReadAllText(keyPath),
                keyPassword
            );
 
            // Preverjanje samopodpisa
            bool signatureValid = loadedCert.VerifySignature(loadedCert);  // samopodpisan
            Console.WriteLine($"Samopodpis veljaven: {signatureValid}");
 
            // Preverjanje pripadnosti para ključev
            bool keyMatch = loadedCert.PublicKeyMatches(loadedKey);
            Console.WriteLine($"Ujemanje javnega ključa: {keyMatch}");
 
            Console.WriteLine("\n✓ Korenski CA uspešno ustvarjen!");
        }
    }
}

Varnostna opozorila

KRITIČNO – Zasebni ključ korenskega CA:

Zasebni ključ korenskega CA je varnostno najkritičnejši element celotne PKI. Kompromitacija pomeni popolno izgubo zaupanja!

  • Nikoli ne generirajte ali shranjujte na omrežnih sistemih
  • Nikoli ne shranjujte nešifrirano
  • Nikoli ne prenašajte po e-pošti ali nezaščitenih kanalih

Priporočeni zaščitni ukrepi:

  • Air-Gapped sistem: Operacije korenskega CA na izoliranem računalniku brez omrežja
  • HSM: Hardware Security Module za shranjevanje ključev (npr. YubiHSM, Thales Luna)
  • Šifriranje: Najmanj AES-256 z močnim geslom (≥20 znakov)
  • Fizična varnost: Šifriran USB ključ v sefu ali bančnem trezorju
  • Varnostna kopija: Najmanj 2 kopiji na ločenih lokacijah
  • Key Ceremony: Dokumentiran proces s pričami za vse operacije korenskega CA
  • Revizijski dnevnik: Beleženje vseh dostopov

Najboljše prakse:

  • ML-DSA-65 ponuja dobro razmerje varnost/zmogljivost za korenske CA
  • pathLength=1 omejuje hierarhijo na Root → Intermediate → End-Entity
  • 20 let veljavnosti je običajno za korenske CA (priporočeno največ 25 let)
  • Nastavitev SKI omogoča kasnejše sklicevanje AKI v vmesnih certifikatih
  • Samopreizkus po generiranju zagotavlja pravilno implementacijo

Povezani scenariji

Povezava Scenarij Opis
Naslednji korak 1.2 Vmesni CA Podpis podrejenega CA s korenskim
Nato 1.4 Shramba zaupanja Distribucija korenskega certifikata
Nato 1.6 CRL/OCSP Vzpostavitev storitev preklica
Alternativno 11.1 Generiranje ključev Samo ključi, brez certifikata
Povezano 11.2 Hramba ključev Dodatne možnosti shranjevanja

« ← PKI infrastruktura | ▲ Scenariji | 1.2 Vmesni CA → »


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