Scenario 10.4: TLS ibrido
Categoria: TLS/mTLS
Complessità: Molto alta
Prerequisiti: OpenSSL 3.6+, certificati PQ
Tempo stimato: 45-60 minuti
Descrizione
Questo scenario descrive il TLS ibrido - la combinazione di algoritmi classici e Post-Quantum nell'handshake TLS per la massima sicurezza nella fase di transizione.
Approcci ibridi:
- Hybrid Key Exchange - X25519 + ML-KEM-768
- Hybrid Signature - ECDSA + ML-DSA-65
- Dual Certificates - Certificato classico + PQ
Perché ibrido? Se un algoritmo viene violato (classico dai computer quantistici, PQ da nuovi attacchi), la connessione rimane sicura grazie all'altro.
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: Combinare entrambi i Shared Secrets
Client->>Server: Finished
Server->>Client: Finished
Note over Client,Server: Connessione protetta ibrida
Esempio codice: TLS ibrido con OpenSSL 3.6
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using System.Runtime.InteropServices; // OpenSSL 3.6 Hybrid Groups per 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) { // Configurare Hybrid Groups (ordine di preferenza) 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("Configurazione hybrid key exchange fallita"); } } }
Server TLS ibrido ASP.NET Core
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 => { // Certificato ibrido (ML-DSA + ECDSA) httpsOptions.ServerCertificate = LoadHybridCertificate(); // Forzare TLS 1.3 (prerequisito per ibrido) httpsOptions.SslProtocols = SslProtocols.Tls13; // Configurazione OpenSSL per Hybrid Key Exchange httpsOptions.OnAuthenticate = (context, sslOptions) => { // Cipher Suites per 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(); // Certificato duale con entrambi gli algoritmi var cert = ctx.LoadCertificateWithPrivateKey( "server-hybrid.crt.pem", "server-hybrid.key.pem", "Password!" ); return cert; }
Creare certificato ibrido
public class HybridCertificateBuilder { public X509Certificate2 CreateHybridServerCertificate( X509Certificate2 caCert, AsymmetricAlgorithm caKey, string[] dnsNames) { using var ctx = PqCryptoContext.Initialize(); // Chiave duale: 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 con entrambe le chiavi var csr = ctx.CreateHybridCertificateRequest( classicalKey: ecdsaKey, pqKey: mlDsaKey, subject: dn, extensions: new ExtBuilder() .SubjectAlternativeName(dnsNames.Select(d => $"dns:{d}").ToArray()) .Build() ); // Emettere certificato ibrido 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) // Estensione specifica ibrida .AddCustomExtension( oid: "1.3.6.1.4.1.99999.1.1", // OID esempio critical: false, value: "hybrid:ecdsa-p384+ml-dsa-65" ) .Build() ); return cert; } }
Nginx con OpenSSL 3.6 ibrido
server { listen 443 ssl http2; server_name www.example.com; # Certificato ibrido ssl_certificate /etc/nginx/ssl/server-hybrid-chain.pem; ssl_certificate_key /etc/nginx/ssl/server-hybrid.key.pem; # Solo TLS 1.3 ssl_protocols TLSv1.3; # Hybrid Key Exchange Groups (OpenSSL 3.6+) ssl_ecdh_curve x25519_mlkem768:secp384r1_mlkem768:X25519:secp384r1; # Algoritmi di firma (ibridi) 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; } }
Configurazione client ibrido
public HttpClient CreateHybridTlsClient() { var handler = new SocketsHttpHandler { SslOptions = new SslClientAuthenticationOptions { EnabledSslProtocols = SslProtocols.Tls13, // Cipher Suites (TLS 1.3 default va bene) 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($"Errore TLS: {errors}"); return false; } // Verificare firma ibrida if (certificate is X509Certificate2 cert2) { var algorithm = cert2.SignatureAlgorithm.FriendlyName; Console.WriteLine($"Algoritmo firma server: {algorithm}"); // Verificare se viene usato algoritmo PQ if (!algorithm.Contains("ML-DSA") && !algorithm.Contains("hybrid")) { Console.WriteLine("AVVISO: Il server non usa certificato PQ"); } } return true; } } }; return new HttpClient(handler); }
Strategia di fallback
public class HybridTlsClientWithFallback { public async Task<HttpResponseMessage> GetWithFallback(string url) { // Tentativo 1: TLS ibrido try { using var hybridClient = CreateHybridTlsClient(); return await hybridClient.GetAsync(url); } catch (AuthenticationException ex) when (IsHybridNotSupported(ex)) { Console.WriteLine("TLS ibrido non supportato, fallback a classico..."); } // Fallback: TLS 1.3 classico 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); } }
Matrice di compatibilità
| Componente | Hybrid Key Exchange | Hybrid Signature |
|---|---|---|
| OpenSSL 3.6+ | Si | Si |
| BoringSSL | Si (sperimentale) | No |
| Windows SChannel | No (non ancora) | No |
| NSS (Firefox) | Si (ML-KEM) | No |
| .NET 9+ | Si (con OpenSSL) | Si |
Requisiti ibridi specifici per settore
| Settore | Timeline | Requisito |
|---|---|---|
| BSI TR-02102 | Dal 2025 | Ibrido raccomandato |
| NIST | Dal 2024 | ML-KEM per Key Exchange |
| Finanza (PCI) | 2025-2027 | Roadmap migrazione PQ |
| Governo | Dal 2025 | Ibrido obbligatorio (US NSA CNSA 2.0) |
Scenari correlati
| Relazione | Scenario | Descrizione |
|---|---|---|
| Prerequisito | 10.1 Server TLS | Setup base |
| Prerequisito | 10.3 Deployment mTLS | Infrastruttura mTLS |
| Correlato | 7.2 Key Encapsulation | ML-KEM |
| Correlato | Algoritmi | Fondamenti PQ |
« ← 10.3 Deployment mTLS | ↑ Panoramica TLS | → Tutti gli scenari »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional
Zuletzt geändert: il 30/01/2026 alle 07:01