Szenario 10.4: Hybrid TLS

Kategorie: TLS/mTLS
Komplexität: ⭐⭐⭐⭐⭐ (Sehr Hoch)
Voraussetzungen: OpenSSL 3.6+, PQ-Zertifikate
Geschätzte Zeit: 45-60 Minuten


Beschreibung

Dieses Szenario beschreibt Hybrid TLS - die Kombination von klassischen und Post-Quantum-Algorithmen im TLS-Handshake für maximale Sicherheit in der Übergangsphase.

Hybrid-Ansätze:

Warum Hybrid? Falls ein Algorithmus gebrochen wird (klassisch durch Quantencomputer, PQ durch neue Angriffe), bleibt die Verbindung durch den anderen sicher.


TLS 1.3 Hybrid Key Exchange

sequenceDiagram participant Client participant Server Client->>Server: ClientHello + key_share(X25519 + ML-KEM-768) Server->>Client: ServerHello + key_share(X25519 + ML-KEM-768) Note over Client,Server: Beide Shared Secrets kombinieren Client->>Server: Finished Server->>Client: Finished Note over Client,Server: Hybrid-gesicherte Verbindung


Code-Beispiel: Hybrid TLS mit OpenSSL 3.6

using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ;
using System.Runtime.InteropServices;
 
// OpenSSL 3.6 Hybrid Groups für Key Exchange
public static class HybridTlsConfig
{
    // Hybrid Key Exchange Groups (OpenSSL 3.6+)
    public const string HYBRID_X25519_MLKEM768 = "x25519_mlkem768";
    public const string HYBRID_SECP384R1_MLKEM768 = "secp384r1_mlkem768";
    public const string HYBRID_SECP256R1_MLKEM512 = "secp256r1_mlkem512";
 
    [DllImport("libssl")]
    private static extern int SSL_CTX_set1_groups_list(IntPtr ctx, string groups);
 
    public static void ConfigureHybridKeyExchange(IntPtr sslContext)
    {
        // Hybrid Groups konfigurieren (Präferenz-Reihenfolge)
        var groups = $"{HYBRID_X25519_MLKEM768}:{HYBRID_SECP384R1_MLKEM768}:X25519:secp384r1";
 
        int result = SSL_CTX_set1_groups_list(sslContext, groups);
        if (result != 1)
        {
            throw new CryptographicException("Failed to configure hybrid key exchange");
        }
    }
}

ASP.NET Core Hybrid TLS Server

using Microsoft.AspNetCore.Server.Kestrel.Core;
using System.Security.Authentication;
 
var builder = WebApplication.CreateBuilder(args);
 
builder.WebHost.ConfigureKestrel(options =>
{
    options.ListenAnyIP(443, listenOptions =>
    {
        listenOptions.UseHttps(httpsOptions =>
        {
            // Hybrid-Zertifikat (ML-DSA + ECDSA)
            httpsOptions.ServerCertificate = LoadHybridCertificate();
 
            // TLS 1.3 erzwingen (Voraussetzung für Hybrid)
            httpsOptions.SslProtocols = SslProtocols.Tls13;
 
            // OpenSSL-Konfiguration für Hybrid Key Exchange
            httpsOptions.OnAuthenticate = (context, sslOptions) =>
            {
                // Cipher Suites für TLS 1.3
                sslOptions.CipherSuitesPolicy = new CipherSuitesPolicy(new[]
                {
                    TlsCipherSuite.TLS_AES_256_GCM_SHA384,
                    TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256
                });
 
                // Application-Layer Protocol Negotiation
                sslOptions.ApplicationProtocols = new List<SslApplicationProtocol>
                {
                    SslApplicationProtocol.Http2,
                    SslApplicationProtocol.Http11
                };
            };
        });
 
        listenOptions.Protocols = HttpProtocols.Http1AndHttp2;
    });
});
 
X509Certificate2 LoadHybridCertificate()
{
    using var ctx = PqCryptoContext.Initialize();
 
    // Dual-Zertifikat mit beiden Algorithmen
    var cert = ctx.LoadCertificateWithPrivateKey(
        "server-hybrid.crt.pem",
        "server-hybrid.key.pem",
        "Password!"
    );
 
    return cert;
}

Hybrid-Zertifikat erstellen

public class HybridCertificateBuilder
{
    public X509Certificate2 CreateHybridServerCertificate(
        X509Certificate2 caCert,
        AsymmetricAlgorithm caKey,
        string[] dnsNames)
    {
        using var ctx = PqCryptoContext.Initialize();
 
        // Dual Key: ECDSA + ML-DSA
        using var ecdsaKey = ECDsa.Create(ECCurve.NamedCurves.nistP384);
        using var mlDsaKey = ctx.GenerateKeyPair(PqAlgorithm.MlDsa65);
 
        var dn = new DnBuilder()
            .AddCN(dnsNames[0])
            .AddO("Example GmbH")
            .Build();
 
        // CSR mit beiden Schlüsseln
        var csr = ctx.CreateHybridCertificateRequest(
            classicalKey: ecdsaKey,
            pqKey: mlDsaKey,
            subject: dn,
            extensions: new ExtBuilder()
                .SubjectAlternativeName(dnsNames.Select(d => $"dns:{d}").ToArray())
                .Build()
        );
 
        // Hybrid-Zertifikat ausstellen
        var cert = ctx.IssueHybridCertificate(
            csr,
            issuerCert: caCert,
            issuerKey: caKey,
            validDays: 365,
            extensions: new ExtBuilder()
                .BasicConstraints(ca: false, critical: true)
                .KeyUsage(KeyUsageFlags.DigitalSignature | KeyUsageFlags.KeyEncipherment)
                .ExtendedKeyUsage(ExtKeyUsage.ServerAuth)
                .SubjectKeyIdentifier(mlDsaKey.PublicKey)
                .AuthorityKeyIdentifier(caCert)
                // Hybrid-spezifische Extension
                .AddCustomExtension(
                    oid: "1.3.6.1.4.1.99999.1.1",  // Beispiel-OID
                    critical: false,
                    value: "hybrid:ecdsa-p384+ml-dsa-65"
                )
                .Build()
        );
 
        return cert;
    }
}

Nginx mit OpenSSL 3.6 Hybrid

server {
    listen 443 ssl http2;
    server_name www.example.com;
 
    # Hybrid-Zertifikat
    ssl_certificate     /etc/nginx/ssl/server-hybrid-chain.pem;
    ssl_certificate_key /etc/nginx/ssl/server-hybrid.key.pem;
 
    # TLS 1.3 only
    ssl_protocols TLSv1.3;
 
    # Hybrid Key Exchange Groups (OpenSSL 3.6+)
    ssl_ecdh_curve x25519_mlkem768:secp384r1_mlkem768:X25519:secp384r1;
 
    # Signature Algorithms (Hybrid)
    ssl_conf_command SignatureAlgorithms ed25519:ecdsa_secp384r1_sha384:mldsa65:hybrid_mldsa65_ecdsa_p384;
 
    # OCSP Stapling
    ssl_stapling on;
    ssl_stapling_verify on;
 
    location / {
        proxy_pass http://backend:8080;
    }
}

Hybrid Client-Konfiguration

public HttpClient CreateHybridTlsClient()
{
    var handler = new SocketsHttpHandler
    {
        SslOptions = new SslClientAuthenticationOptions
        {
            EnabledSslProtocols = SslProtocols.Tls13,
 
            // Cipher Suites (TLS 1.3 default gut)
            CipherSuitesPolicy = new CipherSuitesPolicy(new[]
            {
                TlsCipherSuite.TLS_AES_256_GCM_SHA384,
                TlsCipherSuite.TLS_CHACHA20_POLY1305_SHA256
            }),
 
            RemoteCertificateValidationCallback = (sender, certificate, chain, errors) =>
            {
                if (errors != SslPolicyErrors.None)
                {
                    Console.WriteLine($"TLS Error: {errors}");
                    return false;
                }
 
                // Hybrid-Signatur prüfen
                if (certificate is X509Certificate2 cert2)
                {
                    var algorithm = cert2.SignatureAlgorithm.FriendlyName;
                    Console.WriteLine($"Server Signature Algorithm: {algorithm}");
 
                    // Prüfen ob PQ-Algorithmus verwendet wird
                    if (!algorithm.Contains("ML-DSA") && !algorithm.Contains("hybrid"))
                    {
                        Console.WriteLine("WARNING: Server verwendet kein PQ-Zertifikat");
                    }
                }
 
                return true;
            }
        }
    };
 
    return new HttpClient(handler);
}

Fallback-Strategie

public class HybridTlsClientWithFallback
{
    public async Task<HttpResponseMessage> GetWithFallback(string url)
    {
        // Versuch 1: Hybrid TLS
        try
        {
            using var hybridClient = CreateHybridTlsClient();
            return await hybridClient.GetAsync(url);
        }
        catch (AuthenticationException ex) when (IsHybridNotSupported(ex))
        {
            Console.WriteLine("Hybrid TLS nicht unterstützt, Fallback auf klassisch...");
        }
 
        // Fallback: Klassisches TLS 1.3
        using var classicClient = CreateClassicTlsClient();
        return await classicClient.GetAsync(url);
    }
 
    private bool IsHybridNotSupported(Exception ex)
    {
        return ex.Message.Contains("no common signature algorithm") ||
               ex.Message.Contains("unsupported group");
    }
 
    private HttpClient CreateClassicTlsClient()
    {
        var handler = new HttpClientHandler
        {
            SslProtocols = SslProtocols.Tls13
        };
        return new HttpClient(handler);
    }
}

Kompatibilitätsmatrix

Komponente Hybrid Key Exchange Hybrid Signature
OpenSSL 3.6+
BoringSSL ✅ (experimentell)
Windows SChannel ❌ (noch nicht)
NSS (Firefox) ✅ (ML-KEM)
.NET 9+ ✅ (mit OpenSSL)

Branchenspezifische Hybrid-Anforderungen

Branche Timeline Anforderung
BSI TR-02102 Ab 2025 Hybrid empfohlen
NIST Ab 2024 ML-KEM für Key Exchange
Finanz (PCI) 2025-2027 PQ-Migration Roadmap
Government Ab 2025 Hybrid Pflicht (US NSA CNSA 2.0)

Verwandte Szenarien

Beziehung Szenario Beschreibung
Voraussetzung 10.1 TLS-Server Basis-Setup
Voraussetzung 10.3 mTLS Deployment mTLS-Infrastruktur
Verwandt 7.2 Key Encapsulation ML-KEM
Verwandt Algorithmen PQ-Grundlagen

« ← 10.3 mTLS Deployment | ↑ TLS-Übersicht | → Alle Szenarien »


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