Farbschema: Hell
Sie befinden sich hier: start » de » Dokumentation » Post-Quanten-Kryptografie » WKL.System.Security.Cryptography – Überblick » Erste Schritte » Die erste hybride Zertifikatskette

Die erste hybride Zertifikatskette

Sie stellen für die fiktive Muster GmbH ein hybrides Stammzertifikat und damit ein Serverzertifikat für www.example.com aus und prüfen die Kette – einmal so, wie jede bestehende Software sie prüft, und einmal mit dem Post-Quanten-Anteil. „Hybrid“ heißt: Jedes Zertifikat trägt seine gewohnte RSA-Signatur und zusätzlich eine ML-DSA-Signatur. Software ohne PQ-Kenntnis sieht ein gewöhnliches RSA-Zertifikat.

Voraussetzungen

  • .NET 8 SDK oder höher zum Ausführen des Beispiels, .NET 10 SDK zum Übersetzen der Bibliothek.
  • OpenSSL ab 3.5 für die Prozessarchitektur, siehe Voraussetzungen.
  • Optional für die Gegenprobe in Schritt 6: ein beliebiges OpenSSL-Kommandozeilenwerkzeug ab 3.0.

Schritte

Schritt 1: Projekt anlegen und die Bibliothek einbinden

dotnet new console -n MusterPki -f net8.0
cd MusterPki
dotnet add reference ..\sys-sec-crypto\WKL.System.Security.Cryptography.Extensions.csproj

Passen Sie den Pfad an den Ort an, an dem der Quelltext der Bibliothek liegt.

Schritt 2: OpenSSL einbinden und den hybriden Betrieb einschalten

Ersetzen Sie den Inhalt von Program.cs durch:

using System.Security.Cryptography;
using System.Security.Cryptography.X509Certificates;
using WKL.System.Security.Cryptography;
using WKL.System.Security.Cryptography.X509Certificates;
 
PostQuantumConfig.OpenSslPath = @"C:\OpenSSL\bin";
PostQuantumConfig.EnablePostQuantum(CryptoMode.Hybrid);
Console.WriteLine(PostQuantumConfig.GetOpenSslVersion());

OpenSslPath ist das Verzeichnis mit libcrypto. EnablePostQuantum lädt OpenSSL und wirft eine CryptographicException, wenn es fehlt oder ML-DSA und ML-KEM nicht anbietet. Die Bibliothek arbeitet also nie unbemerkt ohne PQ-Anteil weiter.

Kontrolle: dotnet run gibt die OpenSSL-Version aus, etwa OpenSSL 3.6.1 27 Jan 2026.

Schritt 3: Das hybride Stammzertifikat ausstellen

Hängen Sie an:

using var rootKey = RSA.Create(3072);
var rootRequest = new CertificateRequest(
    "CN=Muster GmbH Root CA", rootKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
rootRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
rootRequest.CertificateExtensions.Add(
    new X509KeyUsageExtension(X509KeyUsageFlags.KeyCertSign | X509KeyUsageFlags.CrlSign, true));
 
using var root = rootRequest.CreateSelfSigned(
    DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(5), CryptoMode.Hybrid);
Console.WriteLine(root.GetSignatureAlgorithmDescription());

Das ist der Aufruf von .NET mit einem zusätzlichen Argument. Ohne CryptoMode.Hybrid entstünde ein gewöhnliches RSA-Zertifikat. Die Bibliothek erzeugt für das Zertifikat ein ML-DSA-65-Schlüsselpaar und hält den privaten Schlüssel für die Laufzeit des Prozesses bereit.

Kontrolle: Die Ausgabe lautet sha256RSA + ML-DSA-65 (Hybrid).

Schritt 4: Das Serverzertifikat ausstellen

using var leafKey = RSA.Create(2048);
var leafRequest = new CertificateRequest(
    "CN=www.example.com", leafKey, HashAlgorithmName.SHA256, RSASignaturePadding.Pkcs1);
 
using var leaf = leafRequest.Create(
    root, DateTimeOffset.UtcNow, DateTimeOffset.UtcNow.AddYears(1),
    RandomNumberGenerator.GetBytes(16), CryptoMode.Hybrid);
using var server = leaf.CopyWithPrivateKey(leafKey);
Console.WriteLine(server.HasPqSignature());

Das Stammzertifikat signiert mit seinem RSA-Schlüssel und mit seinem ML-DSA-Schlüssel aus Schritt 3. Fehlt dieser Schlüssel im Prozess – etwa weil das Stammzertifikat als PEM-Datei statt als PFX geladen wurde –, scheitert der Aufruf mit einer CryptographicException, die den Aussteller nennt.

Kontrolle: Die Ausgabe lautet True.

Schritt 5: Die Kette mit Post-Quanten-Anteil prüfen

using var chain = new X509Chain();
chain.ChainPolicy.TrustMode = X509ChainTrustMode.CustomRootTrust;
chain.ChainPolicy.CustomTrustStore.Add(root);
chain.ChainPolicy.RevocationMode = X509RevocationMode.NoCheck;
 
bool valid = chain.Build(server, CryptoMode.Hybrid);
Console.WriteLine($"Kette gültig: {valid}");
foreach (var element in chain.GetValidationReport().Elements)
{
    Console.WriteLine($"{element.Subject}: {element.PqSignatureStatus}");
}
 
File.WriteAllText("root.pem", root.ExportCertificatePem());
File.WriteAllText("server.pem", server.ExportCertificatePem());

Build mit CryptoMode.Hybrid führt zuerst die gewohnte Prüfung von .NET durch und prüft danach jede ML-DSA-Signatur der Kette. Eine ungültige Signatur ergibt false, wie bei .NET; den klassischen Grund nennt chain.ChainStatus, das PQ-Ergebnis je Zertifikat GetValidationReport().

Kontrolle: Die Ausgabe lautet:

Kette gültig: True
CN=www.example.com: Valid
CN=Muster GmbH Root CA: Valid

Schritt 6: Gegenprobe mit einem klassischen Prüfer

openssl verify -CAfile root.pem server.pem

OpenSSL prüft die RSA-Signaturen und übergeht die nicht kritischen Erweiterungen mit dem PQ-Anteil.

Kontrolle: Die Ausgabe lautet server.pem: OK.

Ergebnis

Sie haben zwei Zertifikate, die jede bestehende Software als RSA-Zertifikate annimmt und deren ML-DSA-Signaturen die Bibliothek zusätzlich prüft. Die privaten ML-DSA-Schlüssel leben nur im laufenden Prozess. Um sie dauerhaft mitzunehmen, exportieren Sie das Zertifikat als PFX.

Nächste Schritte

de/wiki/pqcrypt/lib/getting-started/first-hybrid-certificate-chain.txt · Zuletzt geändert: von Wolfgang van der Stille