Inhaltsverzeichnis

Szenario 1.3: Mehrstufige CA-Hierarchie aufbauen

Kategorie: PKI-Infrastruktur
Komplexität: ⭐⭐⭐⭐ (Hoch)
Voraussetzungen: 1.1 Root-CA, 1.2 Intermediate-CA
Geschätzte Zeit: 1-2 Stunden


Beschreibung

Dieses Szenario beschreibt den Aufbau einer mehrstufigen PKI-Hierarchie mit spezialisierten Intermediate-CAs für verschiedene Verwendungszwecke. Eine gut strukturierte CA-Hierarchie ermöglicht flexible Zertifikatsverwaltung, granulare Sicherheitskontrollen und einfachen Widerruf.

Was wird erstellt:

Vorteile einer strukturierten Hierarchie:


Hierarchie-Modelle

Modell A: 2-stufige Hierarchie (Standard)

                         ┌─────────────────────┐
                         │      Root-CA        │
                         │    (ML-DSA-87)      │
                         │    20 Jahre         │
                         │    pathLen=4        │
                         │    [OFFLINE]        │
                         └──────────┬──────────┘
                                    │
           ┌────────────────────────┼────────────────────────┐
           │                        │                        │
           ▼                        ▼                        ▼
┌─────────────────────┐  ┌─────────────────────┐  ┌─────────────────────┐
│    Server-CA        │  │    Client-CA        │  │   CodeSign-CA       │
│   (ML-DSA-65)       │  │   (ML-DSA-65)       │  │   (ML-DSA-65)       │
│   10 Jahre          │  │   10 Jahre          │  │   10 Jahre          │
│   pathLen=0         │  │   pathLen=0         │  │   pathLen=0         │
│   [ONLINE]          │  │   [ONLINE]          │  │   [HSM]             │
└──────────┬──────────┘  └──────────┬──────────┘  └──────────┬──────────┘
           │                        │                        │
           ▼                        ▼                        ▼
    ┌──────────────┐        ┌──────────────┐        ┌──────────────┐
    │ Server-Certs │        │ Client-Certs │        │ CodeSign-    │
    │ (TLS)        │        │ (mTLS)       │        │ Zertifikate  │
    └──────────────┘        └──────────────┘        └──────────────┘

Eigenschaften:

Modell B: 3-stufige Hierarchie (Enterprise)

                              ┌─────────────────────┐
                              │      Root-CA        │
                              │    (ML-DSA-87)      │
                              │    25 Jahre         │
                              │    pathLen=3        │
                              │    [OFFLINE/HSM]    │
                              └──────────┬──────────┘
                                         │
                    ┌────────────────────┴────────────────────┐
                    │                                         │
                    ▼                                         ▼
         ┌─────────────────────┐               ┌─────────────────────┐
         │    Policy-CA        │               │    Policy-CA        │
         │   (Produktion)      │               │   (Entwicklung)     │
         │   (ML-DSA-65)       │               │   (ML-DSA-65)       │
         │   15 Jahre          │               │   10 Jahre          │
         │   pathLen=1         │               │   pathLen=1         │
         │   [ONLINE/HSM]      │               │   [ONLINE]          │
         └──────────┬──────────┘               └──────────┬──────────┘
                    │                                     │
      ┌─────────────┼─────────────┐           ┌──────────┴──────────┐
      │             │             │           │                     │
      ▼             ▼             ▼           ▼                     ▼
┌───────────┐ ┌───────────┐ ┌───────────┐ ┌───────────┐      ┌───────────┐
│ Server-CA │ │ Client-CA │ │ CodeSign  │ │ Dev-CA    │      │ Test-CA   │
│ (Prod)    │ │ (Prod)    │ │ -CA       │ │           │      │           │
│ pathLen=0 │ │ pathLen=0 │ │ pathLen=0 │ │ pathLen=0 │      │ pathLen=0 │
└─────┬─────┘ └─────┬─────┘ └─────┬─────┘ └─────┬─────┘      └─────┬─────┘
      │             │             │             │                  │
      ▼             ▼             ▼             ▼                  ▼
   Server        Client        Code         Dev-Certs          Test-Certs
   Certs         Certs         Signing

Eigenschaften:

Modell C: Cross-Zertifizierung (Multi-Root)

┌─────────────────────┐                    ┌─────────────────────┐
│   Root-CA (Alt)     │◄──────────────────►│   Root-CA (Neu/PQ)  │
│   (RSA/ECDSA)       │  Cross-Zertifikat  │   (ML-DSA-87)       │
│   [Legacy]          │                    │   [Post-Quantum]    │
└──────────┬──────────┘                    └──────────┬──────────┘
           │                                          │
           ▼                                          ▼
    Legacy Hierarchie                         PQ Hierarchie

Eigenschaften:


Ablaufdiagramm

┌─────────────────────────────────────────────────────────────────────────────┐
│                    CA-HIERARCHIE AUFBAU                                     │
└─────────────────────────────────────────────────────────────────────────────┘

┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 1: Root-CA erstellen (Air-Gapped System)                            │
├─────────────────────────────────────────────────────────────────────────────┤
│  • ML-DSA-87 Schlüsselpaar generieren                                       │
│  • pathLength = Anzahl der geplanten Ebenen                                 │
│  • Gültigkeit: 20-25 Jahre                                                  │
│  • Key offline sichern                                                      │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 2: CA-Struktur planen                                               │
├─────────────────────────────────────────────────────────────────────────────┤
│  • Anzahl und Typen der Intermediate-CAs festlegen                          │
│  • Naming Convention definieren (DN-Struktur)                               │
│  • Certificate Policies pro CA-Typ definieren                               │
│  • Revocation-Strategie planen (CRL/OCSP pro CA)                            │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 3: Policy-CAs erstellen (optional, bei 3-stufiger Hierarchie)       │
├─────────────────────────────────────────────────────────────────────────────┤
│  • CSR erstellen mit pathLength=1                                           │
│  • Von Root-CA signieren lassen                                             │
│  • Certificate Policy OID zuweisen                                          │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 4: Issuing-CAs erstellen                                            │
├─────────────────────────────────────────────────────────────────────────────┤
│  Für jede geplante Issuing-CA:                                              │
│    a) Schlüsselpaar generieren (ML-DSA-65)                                  │
│    b) CSR mit spezifischen Extensions erstellen                             │
│    c) Von übergeordneter CA (Root oder Policy-CA) signieren lassen          │
│    d) EKU (Extended Key Usage) entsprechend Verwendungszweck setzen         │
│    e) pathLength=0 (keine weitere Sub-CA)                                   │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 5: Trust Stores und Chains konfigurieren                            │
├─────────────────────────────────────────────────────────────────────────────┤
│  • Trust Store mit Root-CA erstellen                                        │
│  • CA-Chains für jede Issuing-CA erstellen                                  │
│  • Chains an Clients/Server verteilen                                       │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 6: Revocation-Infrastruktur                                         │
├─────────────────────────────────────────────────────────────────────────────┤
│  • CRL Distribution Points für jede CA einrichten                           │
│  • OCSP-Responder konfigurieren                                             │
│  • Erste (leere) CRLs publizieren                                           │
└─────────────────────────────────────────────────────────────────────────────┘
                                    │
                                    ▼
┌─────────────────────────────────────────────────────────────────────────────┐
│ SCHRITT 7: Dokumentation und Policies                                       │
├─────────────────────────────────────────────────────────────────────────────┤
│  • Certificate Policy (CP) dokumentieren                                    │
│  • Certification Practice Statement (CPS) erstellen                         │
│  • Key Ceremony Dokumentation                                               │
│  • Betriebshandbuch für CA-Administratoren                                  │
└─────────────────────────────────────────────────────────────────────────────┘

Beteiligte Funktionen

Bereich FFI-Funktion Beschreibung
Schlüssel wvds_sec_crypto_x509_keypair_generate_mldsa() ML-DSA Keys für CAs
DN wvds_sec_crypto_x509_dn_create() Distinguished Names
DN wvds_sec_crypto_x509_dn_add_component() CN, O, OU hinzufügen
CSR wvds_sec_crypto_x509_csr_create() CSR erstellen
CSR wvds_sec_crypto_x509_csr_sign() CSR signieren
Extensions wvds_sec_crypto_x509_ext_set_basic_constraints() CA + pathLength
Extensions wvds_sec_crypto_x509_ext_set_key_usage() keyCertSign, cRLSign
Extensions wvds_sec_crypto_x509_ext_set_extended_key_usage() EKU für Spezialisierung
Extensions wvds_sec_crypto_x509_ext_set_certificate_policies() Policy OIDs
Extensions wvds_sec_crypto_x509_ext_set_name_constraints() Namespace-Beschränkungen
Extensions wvds_sec_crypto_x509_ext_set_policy_constraints() Policy-Anforderungen
Zertifikat wvds_sec_crypto_x509_cert_create_from_csr() CA-Zertifikat ausstellen
Chain wvds_sec_crypto_x509_chain_create() Chain-Handle
Chain wvds_sec_crypto_x509_chain_add_cert() Zertifikat hinzufügen
Trust Store wvds_sec_crypto_x509_trust_store_create() Trust Store erstellen
Validierung wvds_sec_crypto_x509_validate_chain() Chain validieren

Code-Beispiel: Vollständige 2-stufige Hierarchie

C# (.NET Wrapper)

using System;
using System.IO;
using System.Collections.Generic;
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
 
namespace CaHierarchyExample
{
    /// <summary>
    /// Erstellt eine vollständige 2-stufige CA-Hierarchie mit spezialisierten Issuing-CAs
    /// </summary>
    class Program
    {
        // Passwörter (in Produktion: sicher eingeben oder aus HSM!)
        static readonly Dictionary<string, string> Passwords = new()
        {
            ["root"]     = "R00t#CA!V3ryStr0ng#2024",
            ["server"]   = "S3rv3r#CA!Str0ng#2024",
            ["client"]   = "Cl13nt#CA!Str0ng#2024",
            ["codesign"] = "C0d3S1gn#CA!Str0ng#2024",
            ["device"]   = "D3v1c3#CA!Str0ng#2024"
        };
 
        // Basis-URLs für Revocation
        const string CRL_BASE_URL = "http://crl.datecpro.de";
        const string OCSP_URL = "http://ocsp.datecpro.de";
        const string CA_ISSUERS_URL = "http://ca.datecpro.de";
 
        static void Main(string[] args)
        {
            using var context = PqCryptoContext.Initialize();
 
            Console.WriteLine("╔══════════════════════════════════════════════════════════╗");
            Console.WriteLine("║     WvdS PQ-Crypto: CA-Hierarchie Aufbau                 ║");
            Console.WriteLine("╚══════════════════════════════════════════════════════════╝\n");
 
            // ══════════════════════════════════════════════════════════════════════
            // SCHRITT 1: Root-CA erstellen
            // ══════════════════════════════════════════════════════════════════════
            Console.WriteLine("┌─────────────────────────────────────────────────────────┐");
            Console.WriteLine("│ SCHRITT 1: Root-CA erstellen                            │");
            Console.WriteLine("└─────────────────────────────────────────────────────────┘\n");
 
            var (rootCert, rootKey) = CreateRootCA(context);
 
            // ══════════════════════════════════════════════════════════════════════
            // SCHRITT 2: Issuing-CAs erstellen
            // ══════════════════════════════════════════════════════════════════════
            Console.WriteLine("\n┌─────────────────────────────────────────────────────────┐");
            Console.WriteLine("│ SCHRITT 2: Issuing-CAs erstellen                        │");
            Console.WriteLine("└─────────────────────────────────────────────────────────┘\n");
 
            var issuingCAs = new List<(PqCertificate cert, string name)>();
 
            // 2.1 Server-CA (für TLS-Server-Zertifikate)
            var serverCA = CreateIssuingCA(context, rootCert, rootKey, new IssuingCAConfig
            {
                Name = "server",
                CommonName = "WvdS Server CA",
                OrganizationalUnit = "TLS Services",
                ExtendedKeyUsage = new[] { ExtendedKeyUsage.ServerAuth },
                ValidYears = 10
            });
            issuingCAs.Add((serverCA, "server"));
 
            // 2.2 Client-CA (für mTLS-Client-Zertifikate)
            var clientCA = CreateIssuingCA(context, rootCert, rootKey, new IssuingCAConfig
            {
                Name = "client",
                CommonName = "WvdS Client CA",
                OrganizationalUnit = "Client Authentication",
                ExtendedKeyUsage = new[] { ExtendedKeyUsage.ClientAuth },
                ValidYears = 10
            });
            issuingCAs.Add((clientCA, "client"));
 
            // 2.3 CodeSign-CA (für Code-Signing)
            var codeSignCA = CreateIssuingCA(context, rootCert, rootKey, new IssuingCAConfig
            {
                Name = "codesign",
                CommonName = "WvdS CodeSign CA",
                OrganizationalUnit = "Code Signing Services",
                ExtendedKeyUsage = new[] { ExtendedKeyUsage.CodeSigning },
                ValidYears = 8  // Kürzer für Code-Signing
            });
            issuingCAs.Add((codeSignCA, "codesign"));
 
            // 2.4 Device-CA (für IoT/Geräte)
            var deviceCA = CreateIssuingCA(context, rootCert, rootKey, new IssuingCAConfig
            {
                Name = "device",
                CommonName = "WvdS Device CA",
                OrganizationalUnit = "IoT and Device Authentication",
                ExtendedKeyUsage = new[] { ExtendedKeyUsage.ClientAuth, ExtendedKeyUsage.ServerAuth },
                ValidYears = 10
            });
            issuingCAs.Add((deviceCA, "device"));
 
            // ══════════════════════════════════════════════════════════════════════
            // SCHRITT 3: CA-Chains erstellen
            // ══════════════════════════════════════════════════════════════════════
            Console.WriteLine("\n┌─────────────────────────────────────────────────────────┐");
            Console.WriteLine("│ SCHRITT 3: CA-Chains erstellen                          │");
            Console.WriteLine("└─────────────────────────────────────────────────────────┘\n");
 
            foreach (var (cert, name) in issuingCAs)
            {
                using var chain = context.CreateCertificateChain();
                chain.Add(cert);
                chain.Add(rootCert);
 
                string chainPath = $"{name}-ca-chain.pem";
                File.WriteAllText(chainPath, chain.ExportToPem());
                Console.WriteLine($"  ✓ {chainPath}");
            }
 
            // Vollständige Chain mit allen CAs
            using var fullChain = context.CreateCertificateChain();
            foreach (var (cert, _) in issuingCAs)
                fullChain.Add(cert);
            fullChain.Add(rootCert);
 
            File.WriteAllText("full-ca-chain.pem", fullChain.ExportToPem());
            Console.WriteLine($"  ✓ full-ca-chain.pem (alle CAs)");
 
            // ══════════════════════════════════════════════════════════════════════
            // SCHRITT 4: Trust Store erstellen
            // ══════════════════════════════════════════════════════════════════════
            Console.WriteLine("\n┌─────────────────────────────────────────────────────────┐");
            Console.WriteLine("│ SCHRITT 4: Trust Store erstellen                        │");
            Console.WriteLine("└─────────────────────────────────────────────────────────┘\n");
 
            using var trustStore = context.CreateTrustStore();
            trustStore.AddCertificate(rootCert);
 
            File.WriteAllText("trust-store.pem", rootCert.ExportToPem());
            Console.WriteLine("  ✓ trust-store.pem (Root-CA)");
 
            // ══════════════════════════════════════════════════════════════════════
            // SCHRITT 5: Validierung
            // ══════════════════════════════════════════════════════════════════════
            Console.WriteLine("\n┌─────────────────────────────────────────────────────────┐");
            Console.WriteLine("│ SCHRITT 5: Hierarchie validieren                        │");
            Console.WriteLine("└─────────────────────────────────────────────────────────┘\n");
 
            foreach (var (cert, name) in issuingCAs)
            {
                // Signatur durch Root prüfen
                bool sigValid = cert.VerifySignature(rootCert);
 
                // Chain-Validierung
                using var testChain = context.CreateCertificateChain();
                testChain.Add(cert);
                testChain.Add(rootCert);
                var result = context.ValidateChain(testChain, trustStore);
 
                Console.WriteLine($"  {name.ToUpper()}-CA:");
                Console.WriteLine($"    Signatur:         {(sigValid ? "✓ OK" : "✗ FEHLER")}");
                Console.WriteLine($"    Chain-Validierung: {(result.IsValid ? "✓ OK" : "✗ FEHLER")}");
            }
 
            // ══════════════════════════════════════════════════════════════════════
            // Zusammenfassung
            // ══════════════════════════════════════════════════════════════════════
            Console.WriteLine("\n╔══════════════════════════════════════════════════════════╗");
            Console.WriteLine("║                    ZUSAMMENFASSUNG                       ║");
            Console.WriteLine("╠══════════════════════════════════════════════════════════╣");
            Console.WriteLine("║ Erstellte CAs:                                           ║");
            Console.WriteLine("║   • Root-CA        (ML-DSA-87, 20 Jahre, pathLen=4)      ║");
            Console.WriteLine("║   • Server-CA      (ML-DSA-65, 10 Jahre, pathLen=0)      ║");
            Console.WriteLine("║   • Client-CA      (ML-DSA-65, 10 Jahre, pathLen=0)      ║");
            Console.WriteLine("║   • CodeSign-CA    (ML-DSA-65,  8 Jahre, pathLen=0)      ║");
            Console.WriteLine("║   • Device-CA      (ML-DSA-65, 10 Jahre, pathLen=0)      ║");
            Console.WriteLine("╠══════════════════════════════════════════════════════════╣");
            Console.WriteLine("║ Erstellte Dateien:                                       ║");
            Console.WriteLine("║   • root-ca.crt.pem / .key.pem                           ║");
            Console.WriteLine("║   • server-ca.crt.pem / .key.pem / -chain.pem            ║");
            Console.WriteLine("║   • client-ca.crt.pem / .key.pem / -chain.pem            ║");
            Console.WriteLine("║   • codesign-ca.crt.pem / .key.pem / -chain.pem          ║");
            Console.WriteLine("║   • device-ca.crt.pem / .key.pem / -chain.pem            ║");
            Console.WriteLine("║   • full-ca-chain.pem / trust-store.pem                  ║");
            Console.WriteLine("╚══════════════════════════════════════════════════════════╝");
 
            // Cleanup
            rootCert.Dispose();
            rootKey.Dispose();
            foreach (var (cert, _) in issuingCAs)
                cert.Dispose();
        }
 
        /// <summary>
        /// Erstellt die Root-CA mit ML-DSA-87
        /// </summary>
        static (PqCertificate cert, PqKeyPair key) CreateRootCA(PqCryptoContext context)
        {
            Console.WriteLine("Generiere Root-CA (ML-DSA-87)...");
 
            // ML-DSA-87 für höchste Sicherheit bei Root-CA
            var keyPair = context.GenerateKeyPair(PqAlgorithm.MlDsa87);
            keyPair.SelfTest();
 
            var dn = new DistinguishedNameBuilder()
                .AddCommonName("WvdS Root CA")
                .AddOrganization("DATECpro GmbH")
                .AddOrganizationalUnit("PKI Services")
                .AddCountry("DE")
                .AddLocality("München")
                .Build();
 
            var extensions = new X509ExtensionsBuilder()
                .AddBasicConstraints(isCa: true, pathLengthConstraint: 4, critical: true)
                .AddKeyUsage(KeyUsageFlags.KeyCertSign | KeyUsageFlags.CrlSign, critical: true)
                .AddSubjectKeyIdentifier(keyPair)
                .Build();
 
            var validity = new CertificateValidity(
                DateTime.UtcNow,
                DateTime.UtcNow.AddYears(20)
            );
 
            var cert = context.CreateRootCertificate(keyPair, dn, validity, extensions);
 
            // Speichern
            File.WriteAllText("root-ca.crt.pem", cert.ExportToPem());
            File.WriteAllText("root-ca.key.pem", keyPair.ExportToEncryptedPem(Passwords["root"]));
 
            Console.WriteLine($"  Subject:    {cert.Subject}");
            Console.WriteLine($"  Serial:     {cert.SerialNumber}");
            Console.WriteLine($"  Algorithm:  ML-DSA-87");
            Console.WriteLine($"  Valid:      {cert.NotBefore:yyyy-MM-dd} - {cert.NotAfter:yyyy-MM-dd}");
            Console.WriteLine($"  pathLength: 4");
            Console.WriteLine($"  ✓ root-ca.crt.pem / root-ca.key.pem gespeichert");
 
            return (cert, keyPair);
        }
 
        /// <summary>
        /// Erstellt eine Issuing-CA mit spezifischer Konfiguration
        /// </summary>
        static PqCertificate CreateIssuingCA(
            PqCryptoContext context,
            PqCertificate issuerCert,
            PqKeyPair issuerKey,
            IssuingCAConfig config)
        {
            Console.WriteLine($"\nErstelle {config.CommonName}...");
 
            // ML-DSA-65 für Issuing-CAs
            var keyPair = context.GenerateKeyPair(PqAlgorithm.MlDsa65);
            keyPair.SelfTest();
 
            var dn = new DistinguishedNameBuilder()
                .AddCommonName(config.CommonName)
                .AddOrganization("DATECpro GmbH")
                .AddOrganizationalUnit(config.OrganizationalUnit)
                .AddCountry("DE")
                .Build();
 
            // Extensions Builder
            var extBuilder = new X509ExtensionsBuilder()
                .AddBasicConstraints(isCa: true, pathLengthConstraint: 0, critical: true)
                .AddKeyUsage(KeyUsageFlags.KeyCertSign | KeyUsageFlags.CrlSign, critical: true)
                .AddSubjectKeyIdentifier(keyPair)
                .AddAuthorityKeyIdentifier(issuerCert)
                .AddCrlDistributionPoint($"{CRL_BASE_URL}/root-ca.crl")
                .AddAuthorityInfoAccess(OCSP_URL, $"{CA_ISSUERS_URL}/root-ca.crt");
 
            // Extended Key Usage (optional, schränkt Verwendung ein)
            if (config.ExtendedKeyUsage?.Length > 0)
            {
                extBuilder.AddExtendedKeyUsage(config.ExtendedKeyUsage, critical: false);
            }
 
            var extensions = extBuilder.Build();
 
            var validity = new CertificateValidity(
                DateTime.UtcNow,
                DateTime.UtcNow.AddYears(config.ValidYears)
            );
 
            // CSR erstellen
            var csr = context.CreateCertificateRequest(dn, keyPair, extensions);
 
            // Von Root-CA signieren
            var cert = context.IssueCertificateFromRequest(
                csr, issuerCert, issuerKey, validity, extensions
            );
 
            // Speichern
            string baseName = config.Name;
            File.WriteAllText($"{baseName}-ca.crt.pem", cert.ExportToPem());
            File.WriteAllText($"{baseName}-ca.key.pem", keyPair.ExportToEncryptedPem(Passwords[baseName]));
 
            Console.WriteLine($"  Subject:    {cert.Subject}");
            Console.WriteLine($"  Issuer:     {cert.Issuer}");
            Console.WriteLine($"  Serial:     {cert.SerialNumber}");
            Console.WriteLine($"  Algorithm:  ML-DSA-65");
            Console.WriteLine($"  Valid:      {cert.NotBefore:yyyy-MM-dd} - {cert.NotAfter:yyyy-MM-dd}");
            Console.WriteLine($"  EKU:        {string.Join(", ", config.ExtendedKeyUsage ?? Array.Empty<ExtendedKeyUsage>())}");
            Console.WriteLine($"  ✓ {baseName}-ca.crt.pem / {baseName}-ca.key.pem gespeichert");
 
            // Key Cleanup (Certificate hält Public Key)
            keyPair.Dispose();
            csr.Dispose();
 
            return cert;
        }
    }
 
    /// <summary>
    /// Konfiguration für eine Issuing-CA
    /// </summary>
    class IssuingCAConfig
    {
        public string Name { get; set; }
        public string CommonName { get; set; }
        public string OrganizationalUnit { get; set; }
        public ExtendedKeyUsage[] ExtendedKeyUsage { get; set; }
        public int ValidYears { get; set; } = 10;
    }
}

Empfohlene Konfiguration pro CA-Typ

Root-CA

Eigenschaft Empfehlung Begründung
Algorithmus ML-DSA-87 Höchste Sicherheit für langlebigen Trust Anchor
Gültigkeit 20-25 Jahre Langlebig, da Änderung aufwendig
pathLength Anzahl Ebenen z.B. 4 für Flexibilität
Key Usage keyCertSign, cRLSign Nur CA-Operationen
Speicherort Offline/HSM Höchster Schutz erforderlich

Policy-CA (optional)

Eigenschaft Empfehlung Begründung
Algorithmus ML-DSA-65 Gutes Sicherheits-/Performance-Verhältnis
Gültigkeit 12-15 Jahre Kürzer als Root
pathLength 1 Erlaubt eine Ebene darunter
Certificate Policies Policy OID Definiert Ausstellungsrichtlinien
Speicherort Online/HSM Seltene Nutzung, hoher Schutz

Server-CA

Eigenschaft Empfehlung Begründung
Algorithmus ML-DSA-65 Balance Sicherheit/Performance
Gültigkeit 8-10 Jahre Kürzere Rotation als Root
pathLength 0 Keine Sub-CAs erlaubt
Key Usage keyCertSign, cRLSign CA-Operationen
Extended Key Usage serverAuth (optional) Einschränkung auf TLS-Server
Speicherort Online (geschützt) Häufige Nutzung für Ausstellung

Client-CA

Eigenschaft Empfehlung Begründung
Algorithmus ML-DSA-65 Balance Sicherheit/Performance
Gültigkeit 8-10 Jahre Standard-Lebensdauer
pathLength 0 Keine Sub-CAs
Extended Key Usage clientAuth Nur Client-Authentifizierung
Name Constraints Optional DNS/Email-Namespace-Beschränkungen

CodeSign-CA

Eigenschaft Empfehlung Begründung
Algorithmus ML-DSA-65 oder ML-DSA-87 Hohe Sicherheit für Code-Signierung
Gültigkeit 6-8 Jahre Kürzere Rotation empfohlen
pathLength 0 Keine Sub-CAs
Extended Key Usage codeSigning Nur Code-Signierung
Speicherort HSM Erhöhter Schutz für Code-Signierung

Device-CA

Eigenschaft Empfehlung Begründung
Algorithmus ML-DSA-44 oder ML-DSA-65 Performance für IoT wichtig
Gültigkeit 8-10 Jahre Geräte-Lebensdauer berücksichtigen
pathLength 0 Keine Sub-CAs
Extended Key Usage clientAuth, serverAuth Beidseitige Kommunikation
Name Constraints Empfohlen Auf Geräte-Namespace beschränken

Extended Key Usage (EKU) OIDs

Verwendungszweck OID CA-Typ
TLS Server Authentication 1.3.6.1.5.5.7.3.1 Server-CA
TLS Client Authentication 1.3.6.1.5.5.7.3.2 Client-CA, Device-CA
Code Signing 1.3.6.1.5.5.7.3.3 CodeSign-CA
Email Protection (S/MIME) 1.3.6.1.5.5.7.3.4 User-CA
Time Stamping 1.3.6.1.5.5.7.3.8 TSA-CA
OCSP Signing 1.3.6.1.5.5.7.3.9 OCSP-Responder

EKU-Vererbung: Wenn eine CA ein EKU hat, dürfen ausgestellte Zertifikate nur EKUs haben, die eine Teilmenge der CA-EKUs sind. Eine Server-CA mit nur serverAuth kann keine Zertifikate mit clientAuth ausstellen.


Name Constraints

Name Constraints beschränken den Namespace, in dem eine CA Zertifikate ausstellen darf.

wvds_sec_crypto_x509_ext_set_name_constraints(
    ext,
    permitted_dns: ["datecpro.de", ".datecpro.de"],
    permitted_email: ["@datecpro.de"],
    excluded_dns: ["external.datecpro.de"],
    critical: true
)

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