Farbschema: Hell
Sie befinden sich hier: start » de » Dokumentation » Post-Quanten-Kryptografie » WKL.System.Security.Cryptography – Überblick » Anleitungen » So verschlüsseln Sie CMS-Nachrichten

So verschlüsseln Sie CMS-Nachrichten

Sie verschlüsseln Daten für einen Empfänger, dessen Zertifikat einen ML-KEM-Schlüssel trägt, etwa für ein Archiv, dessen Inhalt auch gegen künftige Quantenrechner vertraulich bleiben soll.

Lösungsübersicht

ElementZweck
PostQuantumConfig.Exemptionserlaubt mit PurePostQuantum reine ML-KEM-Empfänger und den ML-DSA-Aussteller
MLKemKey.Generateerzeugt ein ML-KEM-Schlüsselpaar (ML-KEM-768 oder ML-KEM-1024; ML-KEM-512 nur mit ReducedParameterSets)
X509CertificateBuilder mit einem ML-KEM-Schlüsselstellt das Empfängerzertifikat aus
AttachPrivateMLKemKeyordnet dem Empfängerzertifikat seinen privaten Schlüssel zu
KemEnvelopedCms.Encrypt, Encodeverschlüsselt den Inhalt für einen oder mehrere Empfänger
KemEnvelopedCms.Decode, Decryptentschlüsselt beim Empfänger

KemEnvelopedCms ist wie EnvelopedCms von .NET aufgebaut.

Umsetzung

BSI TR-02102-1 empfiehlt ML-KEM nur in Kombination mit einem klassischen Verfahren und dafür die Kombinierer CatKDF oder KeyCombine. Ein KEMRecipientInfo nach RFC 9629 verwendet ML-KEM allein, Composite ML-KEM kombiniert mit SHA3-256. Beide Empfängerarten brauchen deshalb eine Freischaltung, die Sie einmal beim Start der Anwendung setzen; im Beispiel PurePostQuantum für den ML-KEM-Empfänger und die reine ML-DSA-Zertifizierungsstelle:

PostQuantumConfig.Exemptions |= PostQuantumExemptions.PurePostQuantum;

Empfängerzertifikat; ein ML-KEM-Schlüssel kann nicht signieren, deshalb stellt ein ML-DSA-Aussteller das Zertifikat aus. Im Beispiel ist das eine eigene Zertifizierungsstelle:

var now = DateTimeOffset.UtcNow;
using var caKey = MLDsaKey.Generate(MLDsaParameterSet.MLDsa65);
var caRequest = new MLDsaX509SignatureGenerator(caKey).CreateCertificateRequest("CN=Muster GmbH PQ CA");
caRequest.CertificateExtensions.Add(new X509BasicConstraintsExtension(true, false, 0, true));
caRequest.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyCertSign, true));
using var ca = caRequest.CreateSelfSigned(now, now.AddYears(10), CryptoMode.PostQuantum);
 
using var archiveKey = MLKemKey.Generate(MLKemParameterSet.MLKem768);
var archiveBuilder = new X509CertificateBuilder(
    new X500DistinguishedName("CN=Muster GmbH Archiv"), archiveKey.ExportSubjectPublicKeyInfo(), default);
archiveBuilder.CertificateExtensions.Add(new X509KeyUsageExtension(X509KeyUsageFlags.KeyEncipherment, true));
using var archive = archiveBuilder.Create(
    ca, now, now.AddYears(1), RandomNumberGenerator.GetBytes(16), CryptoMode.PostQuantum);
archive.AttachPrivateMLKemKey(archiveKey);

Verschlüsseln und entschlüsseln:

var outgoing = new KemEnvelopedCms(new ContentInfo("Vertrag 2026-17"u8.ToArray()));
outgoing.Encrypt(archive);
byte[] envelope = outgoing.Encode();
 
var incoming = new KemEnvelopedCms();
incoming.Decode(envelope);
incoming.Decrypt(archive);
Console.WriteLine(System.Text.Encoding.UTF8.GetString(incoming.ContentInfo.Content));

Hinweise

  • Nur mit KemEnvelopedCms lesbar. EnvelopedCms von .NET kann Nachrichten mit KEMRecipientInfo nicht dekodieren, auch nicht für einen RSA-Empfänger derselben Nachricht.
  • Hybrid über Composite ML-KEM. Trägt das Empfängerzertifikat einen Composite-ML-KEM-Schlüssel, bleibt der Inhalt vertraulich, solange einer der beiden Anteile hält. Ordnen Sie den privaten Schlüssel dann mit AttachPrivateCompositeMLKemKey zu. Das Verschlüsseln für einen solchen Empfänger braucht PostQuantumExemptions.NonRecommendedCombiners; das Entschlüsseln vorhandener Nachrichten braucht keine Freischaltung und meldet das Ereignis PolicyDeviation.
  • Hybrid ohne CMS. Für ein eigenes Protokoll ohne CMS vereinbart HybridKeyAgreement einen Schlüssel aus ECDH und ML-KEM mit KeyCombine, ohne Freischaltung; siehe So vereinbaren Sie einen hybriden Schlüssel.
  • RSA-Empfänger in derselben Nachricht. Ein Empfänger mit RSA-Zertifikat erhält eine KeyTransRecipientInfo mit RSAES-OAEP. Auch er öffnet die Nachricht mit KemEnvelopedCms.
  • Der private Schlüssel muss im Prozess sein. Decrypt braucht den privaten ML-KEM-Schlüssel des Empfängers. Fehlt er, scheitert der Aufruf mit einer CryptographicException.

Verwandte Themen

de/wiki/pqcrypt/lib/how-to/encrypt-cms-messages.txt · Zuletzt geändert: von Wolfgang van der Stille