Kategorie: Verschlüsselung
Komplexität: ⭐⭐⭐ (Mittel)
Voraussetzungen: ML-KEM-Schlüsselpaar
Geschätzte Zeit: 15-20 Minuten
Dieses Szenario beschreibt Key Encapsulation mit ML-KEM (Module-Lattice-based Key Encapsulation Mechanism, NIST FIPS 203). ML-KEM ist ein Post-Quantum Key Encapsulation Mechanism (KEM), der sicher gegen Quantencomputer-Angriffe ist.
KEM vs. Key Exchange:
| Aspekt | Key Exchange (DH) | Key Encapsulation (KEM) |
|---|---|---|
| Interaktivität | Beide Parteien aktiv | Nur Sender aktiv |
| Schlüsselerzeugung | Gemeinsam berechnet | Zufällig generiert |
| Anwendung | TLS Handshake | Verschlüsselung, hybride TLS |
| Parameter | Sicherheit | Public Key | Ciphertext | Shared Secret |
|---|---|---|---|---|
| ML-KEM-512 | 128-bit | 800 Bytes | 768 Bytes | 32 Bytes |
| ML-KEM-768 | 192-bit | 1,184 Bytes | 1,088 Bytes | 32 Bytes |
| ML-KEM-1024 | 256-bit | 1,568 Bytes | 1,568 Bytes | 32 Bytes |
Empfehlung: ML-KEM-768 für die meisten Anwendungen (BSI empfiehlt mindestens 192-bit).
using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using var ctx = PqCryptoContext.Initialize(); // ML-KEM-768 Schlüsselpaar generieren using var mlKemKeyPair = ctx.GenerateKeyPair(PqAlgorithm.MlKem768); // Public Key exportieren (für Sender) var publicKeyPem = mlKemKeyPair.PublicKey.ToPem(); File.WriteAllText("recipient-mlkem.pub.pem", publicKeyPem); // Private Key verschlüsselt speichern mlKemKeyPair.ToEncryptedPemFile("recipient-mlkem.key.pem", "SecurePassword!"); Console.WriteLine("ML-KEM-768 Schlüsselpaar generiert:"); Console.WriteLine($" Public Key: {mlKemKeyPair.PublicKey.GetRawData().Length} Bytes"); Console.WriteLine($" Algorithm OID: {mlKemKeyPair.PublicKey.Oid.Value}");
using var ctx = PqCryptoContext.Initialize(); // Empfänger Public Key laden var recipientPublicKey = ctx.LoadPublicKey("recipient-mlkem.pub.pem"); // Key Encapsulation durchführen var (ciphertext, sharedSecret) = ctx.Encapsulate(recipientPublicKey); Console.WriteLine($"Encapsulation abgeschlossen:"); Console.WriteLine($" Ciphertext: {ciphertext.Length} Bytes"); Console.WriteLine($" Shared Secret: {sharedSecret.Length} Bytes"); Console.WriteLine($" Shared Secret (hex): {Convert.ToHexString(sharedSecret)}"); // Ciphertext an Empfänger senden File.WriteAllBytes("ciphertext.bin", ciphertext); // Shared Secret für Verschlüsselung verwenden var encryptionKey = ctx.DeriveKey( sharedSecret, outputLength: 32, info: Encoding.UTF8.GetBytes("aes-encryption-key") );
using var ctx = PqCryptoContext.Initialize(); // Private Key laden var privateKey = ctx.LoadPrivateKey("recipient-mlkem.key.pem", "SecurePassword!"); // Ciphertext empfangen var ciphertext = File.ReadAllBytes("ciphertext.bin"); // Decapsulation durchführen var sharedSecret = ctx.Decapsulate(privateKey, ciphertext); Console.WriteLine($"Decapsulation abgeschlossen:"); Console.WriteLine($" Shared Secret: {sharedSecret.Length} Bytes"); Console.WriteLine($" Shared Secret (hex): {Convert.ToHexString(sharedSecret)}"); // Gleichen Schlüssel ableiten wie Sender var decryptionKey = ctx.DeriveKey( sharedSecret, outputLength: 32, info: Encoding.UTF8.GetBytes("aes-encryption-key") );
public class MlKemService { private readonly PqCryptoContext _ctx; public MlKemService() { _ctx = PqCryptoContext.Initialize(); } public (byte[] PublicKey, byte[] PrivateKey) GenerateKeyPair(MlKemParameterSet paramSet = MlKemParameterSet.MlKem768) { var algorithm = paramSet switch { MlKemParameterSet.MlKem512 => PqAlgorithm.MlKem512, MlKemParameterSet.MlKem768 => PqAlgorithm.MlKem768, MlKemParameterSet.MlKem1024 => PqAlgorithm.MlKem1024, _ => throw new ArgumentException("Invalid parameter set") }; using var keyPair = _ctx.GenerateKeyPair(algorithm); return ( keyPair.PublicKey.GetRawData(), keyPair.PrivateKey.GetRawData() ); } public (byte[] Ciphertext, byte[] SharedSecret) Encapsulate(byte[] publicKey) { using var pubKey = _ctx.ImportPublicKey(publicKey); return _ctx.Encapsulate(pubKey); } public byte[] Decapsulate(byte[] privateKey, byte[] ciphertext) { using var privKey = _ctx.ImportPrivateKey(privateKey); return _ctx.Decapsulate(privKey, ciphertext); } } public enum MlKemParameterSet { MlKem512, MlKem768, MlKem1024 }
try { var sharedSecret = ctx.Decapsulate(privateKey, ciphertext); } catch (CryptographicException ex) when (ex.Message.Contains("decapsulation")) { // Decapsulation fehlgeschlagen - Ciphertext manipuliert oder falscher Schlüssel Console.WriteLine("Decapsulation fehlgeschlagen: Ciphertext ungültig"); throw new SecurityException("Integrity check failed", ex); } catch (ArgumentException ex) { // Falsches Format Console.WriteLine($"Format-Fehler: {ex.Message}"); throw; }
Sicherheitshinweis: ML-KEM ist IND-CCA2 sicher. Bei Decapsulation-Fehlern wird ein deterministischer, aber unvorhersagbarer Wert zurückgegeben (implizite Ablehnung). Dies verhindert Chosen-Ciphertext-Angriffe.
| Branche | Empfohlener Parameter | Begründung |
|---|---|---|
| Standard IT | ML-KEM-768 | Gute Balance |
| Finanzsektor | ML-KEM-768/1024 | Regulatorische Anforderungen |
| Healthcare | ML-KEM-768 | Langzeit-Datenschutz |
| Government | ML-KEM-1024 | Höchste Sicherheit |
| IoT/Embedded | ML-KEM-512 | Ressourcenbeschränkt |
| Beziehung | Szenario | Beschreibung |
|---|---|---|
| Anwendung | 7.1 Hybrid-Verschlüsselung | Kombination mit klassisch |
| Anwendung | 7.3 Dateiverschlüsselung | Praktische Nutzung |
| Verwandt | 11.1 Schlüsselgenerierung | Key Generation |
| Verwandt | 10.4 Hybrid TLS | TLS mit ML-KEM |
« ← 7.1 Hybrid-Verschlüsselung | ↑ Verschlüsselung-Übersicht | 7.3 Dateiverschlüsselung → »
Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional