====== Szenario 1.3: Mehrstufige CA-Hierarchie aufbauen ======
**Kategorie:** [[.:start|PKI-Infrastruktur]] \\
**Komplexität:** ⭐⭐⭐⭐ (Hoch) \\
**Voraussetzungen:** [[.:root_ca_erstellen|1.1 Root-CA]], [[.:intermediate_ca_erstellen|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:**
* Root-CA (Offline, Trust Anchor)
* Policy-CA (optional, für große Organisationen)
* Mehrere spezialisierte Issuing-CAs:
* **Server-CA:** TLS-Server-Zertifikate
* **Client-CA:** mTLS-Client-Zertifikate
* **User-CA:** S/MIME und Benutzer-Authentifizierung
* **CodeSign-CA:** Code-Signing-Zertifikate
* **Device-CA:** IoT/Geräte-Zertifikate
**Vorteile einer strukturierten Hierarchie:**
* **Trennung der Verantwortlichkeiten:** Verschiedene Teams verwalten verschiedene CAs
* **Granularer Widerruf:** Eine kompromittierte CA betrifft nur einen Bereich
* **Compliance:** Unterschiedliche Policies pro Verwendungszweck
* **Skalierbarkeit:** Neue CAs können einfach hinzugefügt werden
* **Audit:** Klare Zuordnung von Zertifikaten zu ausstellender CA
----
===== 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:**
* Einfach zu verwalten
* Root-CA signiert direkt alle Issuing-CAs
* Geeignet für kleine bis mittlere Organisationen
==== 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:**
* Höhere Sicherheit durch zusätzliche Ebene
* Trennung von Produktion und Entwicklung
* Policy-CAs können verschiedene Certificate Policies haben
* Geeignet für große Organisationen mit Compliance-Anforderungen
==== 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:**
* Ermöglicht Migration von klassischer zu PQ-Kryptographie
* Beide Root-CAs sind gegenseitig vertrauenswürdig
* Clients können beiden Hierarchien vertrauen
----
===== 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
{
///
/// Erstellt eine vollständige 2-stufige CA-Hierarchie mit spezialisierten Issuing-CAs
///
class Program
{
// Passwörter (in Produktion: sicher eingeben oder aus HSM!)
static readonly Dictionary 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();
}
///
/// Erstellt die Root-CA mit ML-DSA-87
///
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);
}
///
/// Erstellt eine Issuing-CA mit spezifischer Konfiguration
///
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())}");
Console.WriteLine($" ✓ {baseName}-ca.crt.pem / {baseName}-ca.key.pem gespeichert");
// Key Cleanup (Certificate hält Public Key)
keyPair.Dispose();
csr.Dispose();
return cert;
}
}
///
/// Konfiguration für eine Issuing-CA
///
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
)
{{tag>szenario pki hierarchie root-ca intermediate-ca policy-ca eku name-constraints}}
----
//Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//