~~NOTOC~~ ====== Scenario 7.2: Key Encapsulation (ML-KEM) ====== **Category:** [[.:start|Encryption]] \\ **Complexity:** *** (Medium) \\ **Prerequisites:** ML-KEM key pair \\ **Estimated Time:** 15-20 minutes ---- ===== Description ===== This scenario describes **Key Encapsulation** with ML-KEM (Module-Lattice-based Key Encapsulation Mechanism, NIST FIPS 203). ML-KEM is a Post-Quantum Key Encapsulation Mechanism (KEM) that is secure against quantum computer attacks. **KEM vs. Key Exchange:** ^ Aspect ^ Key Exchange (DH) ^ Key Encapsulation (KEM) ^ | Interactivity | Both parties active | Only sender active | | Key generation | Jointly computed | Randomly generated | | Application | TLS handshake | Encryption, hybrid TLS | ---- ===== ML-KEM Parameter Sets ===== ^ Parameter ^ Security ^ 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 | **Recommendation:** ML-KEM-768 for most applications (BSI recommends at least 192-bit). ---- ===== Workflow ===== flowchart LR subgraph Recipient GEN[KeyGen] --> PK[Public Key] GEN --> SK[Secret Key] end subgraph Sender PK --> ENC[Encapsulate] ENC --> CT[Ciphertext] ENC --> SS1[Shared Secret] end subgraph Recipient2[Recipient] CT --> DEC[Decapsulate] SK --> DEC DEC --> SS2[Shared Secret] end SS1 -.->|equal| SS2 style SS1 fill:#e8f5e9 style SS2 fill:#e8f5e9 ---- ===== Code Example: Generate Key Pair ===== using WvdS.Security.Cryptography.X509Certificates.Extensions.PQ; using var ctx = PqCryptoContext.Initialize(); // Generate ML-KEM-768 key pair using var mlKemKeyPair = ctx.GenerateKeyPair(PqAlgorithm.MlKem768); // Export public key (for sender) var publicKeyPem = mlKemKeyPair.PublicKey.ToPem(); File.WriteAllText("recipient-mlkem.pub.pem", publicKeyPem); // Save private key encrypted mlKemKeyPair.ToEncryptedPemFile("recipient-mlkem.key.pem", "SecurePassword!"); Console.WriteLine("ML-KEM-768 key pair generated:"); Console.WriteLine($" Public Key: {mlKemKeyPair.PublicKey.GetRawData().Length} bytes"); Console.WriteLine($" Algorithm OID: {mlKemKeyPair.PublicKey.Oid.Value}"); ---- ===== Code Example: Encapsulation (Sender) ===== using var ctx = PqCryptoContext.Initialize(); // Load recipient public key var recipientPublicKey = ctx.LoadPublicKey("recipient-mlkem.pub.pem"); // Perform key encapsulation var (ciphertext, sharedSecret) = ctx.Encapsulate(recipientPublicKey); Console.WriteLine($"Encapsulation completed:"); Console.WriteLine($" Ciphertext: {ciphertext.Length} bytes"); Console.WriteLine($" Shared Secret: {sharedSecret.Length} bytes"); Console.WriteLine($" Shared Secret (hex): {Convert.ToHexString(sharedSecret)}"); // Send ciphertext to recipient File.WriteAllBytes("ciphertext.bin", ciphertext); // Use shared secret for encryption var encryptionKey = ctx.DeriveKey( sharedSecret, outputLength: 32, info: Encoding.UTF8.GetBytes("aes-encryption-key") ); ---- ===== Code Example: Decapsulation (Recipient) ===== using var ctx = PqCryptoContext.Initialize(); // Load private key var privateKey = ctx.LoadPrivateKey("recipient-mlkem.key.pem", "SecurePassword!"); // Receive ciphertext var ciphertext = File.ReadAllBytes("ciphertext.bin"); // Perform decapsulation var sharedSecret = ctx.Decapsulate(privateKey, ciphertext); Console.WriteLine($"Decapsulation completed:"); Console.WriteLine($" Shared Secret: {sharedSecret.Length} bytes"); Console.WriteLine($" Shared Secret (hex): {Convert.ToHexString(sharedSecret)}"); // Derive same key as sender var decryptionKey = ctx.DeriveKey( sharedSecret, outputLength: 32, info: Encoding.UTF8.GetBytes("aes-encryption-key") ); ---- ===== Wrapper Class for ML-KEM ===== 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 } ---- ===== Error Handling ===== try { var sharedSecret = ctx.Decapsulate(privateKey, ciphertext); } catch (CryptographicException ex) when (ex.Message.Contains("decapsulation")) { // Decapsulation failed - ciphertext tampered or wrong key Console.WriteLine("Decapsulation failed: Ciphertext invalid"); throw new SecurityException("Integrity check failed", ex); } catch (ArgumentException ex) { // Wrong format Console.WriteLine($"Format error: {ex.Message}"); throw; } **Security Note:** ML-KEM is IND-CCA2 secure. On decapsulation failures, a deterministic but unpredictable value is returned (implicit rejection). This prevents chosen-ciphertext attacks. ---- ===== Industry-Specific Parameters ===== ^ Industry ^ Recommended Parameter ^ Rationale ^ | **Standard IT** | ML-KEM-768 | Good balance | | **Financial Sector** | ML-KEM-768/1024 | Regulatory requirements | | **Healthcare** | ML-KEM-768 | Long-term data protection | | **Government** | ML-KEM-1024 | Highest security | | **IoT/Embedded** | ML-KEM-512 | Resource-constrained | ---- ===== Related Scenarios ===== ^ Relationship ^ Scenario ^ Description ^ | **Application** | [[.:hybrid_encryption|7.1 Hybrid Encryption]] | Combination with classical | | **Application** | [[.:file_encryption|7.3 File Encryption]] | Practical usage | | **Related** | [[en:int:pqcrypt:szenarien:schluessel:generierung|11.1 Key Generation]] | Key generation | | **Related** | [[en:int:pqcrypt:szenarien:tls:hybrid_tls|10.4 Hybrid TLS]] | TLS with ML-KEM | ---- << [[.:hybrid_encryption|<- 7.1 Hybrid Encryption]] | [[.:start|^ Encryption Overview]] | [[.:file_encryption|7.3 File Encryption ->]] >> {{tag>scenario encryption ml-kem kem post-quantum fips203}} ---- //Wolfgang van der Stille @ EMSR DATA d.o.o. - Post-Quantum Cryptography Professional//