Entwicklung & Code
Neu in .NET 10.0 [30]: Algorithmen für die Post-Quanten-Kryptografie
.NET 10.0 enthält drei neue asymmetrische Kryptografie-Algorithmen: ML-KEM (FIPS 203), ML-DSA (FIPS 204) und SLH-DSA (FIPS 205), die im August 2024 die US-amerikanischen Bundesbehörde National Institute of Standards and Technology (NIST) verabschiedet hat.
Weiterlesen nach der Anzeige
Dr. Holger Schwichtenberg ist technischer Leiter des Expertennetzwerks www.IT-Visions.de, das mit 53 renommierten Experten zahlreiche mittlere und große Unternehmen durch Beratungen und Schulungen sowie bei der Softwareentwicklung unterstützt. Durch seine Auftritte auf zahlreichen nationalen und internationalen Fachkonferenzen sowie mehr als 90 Fachbücher und mehr als 1500 Fachartikel gehört Holger Schwichtenberg zu den bekanntesten Experten für .NET und Webtechniken in Deutschland.
Federal Information Processing Standards (FIPS) sind offizielle technische Standards des NIST:
| FIPS | Algorithmus | Zweck | .NET-10.0-Klasse |
| 203 | ML‑KEM (CRYSTALS‑Kyber) | Schlüsselaustausch für AES u.a. | System.Security.Cryptography.MLKem |
| 204 | ML‑DSA (CRYSTALS‑Dilithium) | Digitale Signatur zur Authentifizierung und Datenintegrität | System.Security.Cryptography.MLDsa |
| 205 | SLH‑DSA (SPHINCS+) | Digitale Signatur (Alternative Signaturen, falls später bei ML‑DSA Schwächen entdeckt werden.) | System.Security.Cryptography.SlhDsa |
| 206 | FN‑DSA (FALCON) | Digitale Signatur (geplantes weiteres optionales Signaturverfahren) | keine |
Diese Kryptografie-Algorithmen gehören zur Klasse Post-Quanten-Kryptografie (Post-Quantum Cryptography, PQC). Das sind neuere kryptografische Verfahren, die selbst dann sicher bleiben sollen, wenn leistungsstarke Quantencomputer verfügbar sind. Heute etablierte Algorithmen wie RSA und ECC basieren auf mathematischen Problemen, die Quantencomputer recht schnell lösen können. PQC-Algorithmen sollen auch mit Quantencomputern nicht schnell angreifbar sein.
(Bild: King / stock.adobe.com)
Das ist neu in .NET 11.0: Dr. Holger Schwichtenberg und weitere Experten präsentieren am 17. November 2026 auf der Online-Konferenz betterCode() .NET 11.0 die Änderungen für Entwicklerinnen und Entwickler. Das Programm steht jetzt fest, Tickets zum Frühbucherpreis sind verfügbar.
Die neuen Klassen findet man im .NET-Namensraum System.Security.Cryptography:
System.Security.Cryptography.MLKemSystem.Security.Cryptography.MLDsaSystem.Security.Cryptography.SlhDsa
Weiterlesen nach der Anzeige
Microsoft will aber FIPS 206 nicht implementieren: „We do not believe there is a need for any FIPS 206 algorithms in .NET workloads, they are planned as ’never’ until evidence suggests otherwise.“
Windows liefert diese Algorithmen in der Cryptography Next Generation API (CNG) seit Windows Insiders, Canary Channel Build 27852 oder höher mit. Eine stabile Version gibt es seit Windows 11 25H2 und Windows Server 2025. Für macOS- und Linux-Systeme braucht man die OpenSSL-Bibliothek ab Version 3.5. Folgender Code zeigt einige Beispiele für PQC:
using System.Security.Cryptography;
namespace NET10_Console;
public class FCL10_PQC
{
public void GetSupportedStandards()
{
CUI.Demo("Post-Quantum Cryptography (PQC) in .NET 10.0");
CUI.H2("Prüfung, ob die PQC-Algorithmen verfügbar sind");
Console.WriteLine("ML-KEM (FIPS 203) für Verschlüsselung: " + System.Security.Cryptography.MLKem.IsSupported);
Console.WriteLine("ML-DSA (FIPS 204) für Digitale Signaturen: " + System.Security.Cryptography.MLDsa.IsSupported);
#pragma warning disable SYSLIB5006 // Type is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
Console.WriteLine("SLH-DSA (FIPS 205) für Digitale Signaturen (Alternative/Reserve): " + System.Security.Cryptography.SlhDsa.IsSupported);
}
///
public void KEMDemo()
{
CUI.Demo(nameof(KEMDemo) + ": Verschlüsselung mit AES unter Verwendung von ML-KEM zum Schlüsselaustausch");
try
{
string originalText = "Dies ist ein vertraulicher Text, der mit Post-Quantum Cryptography geschützt wird!";
CUI.H2("Originaltext");
Console.WriteLine(originalText);
// 1. Empfänger generiert Schlüsselpaar
CUI.H2("1. Schlüsselpaar generieren (Empfänger)");
using MLKem receiverKey = MLKem.GenerateKey(MLKemAlgorithm.MLKem1024);
// Export/Import als PEM
string publicKeyPem = receiverKey.ExportSubjectPublicKeyInfoPem();
Console.WriteLine($"Öffentlicher Schlüssel (PEM): {publicKeyPem.Substring(0, Math.Min(80, publicKeyPem.Length))}...");
// 2. Sender verwendet öffentlichen Schlüssel für Encapsulation
CUI.H2("2. Gemeinsames Geheimnis erzeugen (Sender)");
using MLKem senderKey = MLKem.ImportFromPem(publicKeyPem);
// ML-KEM 1024: Ciphertext = 1568 Bytes, Shared Secret = 32 Bytes
byte[] ciphertext = new byte[1568];
byte[] sharedSecretSender = new byte[32];
senderKey.Encapsulate(ciphertext, sharedSecretSender);
Console.WriteLine($"Ciphertext Größe: {ciphertext.Length} Bytes");
Console.WriteLine($"Gemeinsames Geheimnis (Sender): {Convert.ToHexString(sharedSecretSender)}");
// 3. Sender verschlüsselt Daten mit AES unter Verwendung des gemeinsamen Geheimnisses
CUI.H2("3. Daten mit AES verschlüsseln (Sender)");
byte[] encryptedData;
byte[] iv;
using (Aes aes = Aes.Create())
{
aes.Key = sharedSecretSender;
aes.GenerateIV();
iv = aes.IV;
using ICryptoTransform encryptor = aes.CreateEncryptor();
byte[] plainBytes = System.Text.Encoding.UTF8.GetBytes(originalText);
encryptedData = encryptor.TransformFinalBlock(plainBytes, 0, plainBytes.Length);
}
Console.WriteLine($"Verschlüsselte Daten: {Convert.ToHexString(encryptedData)}");
Console.WriteLine($"IV: {Convert.ToHexString(iv)}");
// 4. Empfänger extrahiert gemeinsames Geheimnis mit Decapsulation
CUI.H2("4. Gemeinsames Geheimnis extrahieren (Empfänger)");
byte[] sharedSecretReceiver = new byte[32];
receiverKey.Decapsulate(ciphertext, sharedSecretReceiver);
Console.WriteLine($"Gemeinsames Geheimnis (Empfänger): {Convert.ToHexString(sharedSecretReceiver)}");
Console.WriteLine($"Geheimnisse identisch: {sharedSecretSender.SequenceEqual(sharedSecretReceiver)}");
// 5. Empfänger entschlüsselt Daten mit AES
CUI.H2("5. Daten mit AES entschlüsseln (Empfänger)");
string decryptedText;
using (Aes aes = Aes.Create())
{
aes.Key = sharedSecretReceiver;
aes.IV = iv;
using ICryptoTransform decryptor = aes.CreateDecryptor();
byte[] decryptedBytes = decryptor.TransformFinalBlock(encryptedData, 0, encryptedData.Length);
decryptedText = System.Text.Encoding.UTF8.GetString(decryptedBytes);
}
CUI.H2("Entschlüsselter Text");
CUI.Green(decryptedText);
CUI.Success($"Verschlüsselung erfolgreich: {originalText == decryptedText}");
}
catch (Exception ex)
{
CUI.Error(ex);
}
}
///
public void DSADemo()
{
CUI.Demo(nameof(DSADemo) + ": ML-DSA (FIPS 204) - Post-Quantum Digitale Signaturen");
try
{
string originalText = "Dieses Dokument muss digital signiert werden, um Integrität und Authentizität zu gewährleisten.";
CUI.H2("Originaldokument");
Console.WriteLine(originalText);
byte[] data = System.Text.Encoding.UTF8.GetBytes(originalText);
// 1. Sender generiert Schlüsselpaar
CUI.H2("1. Schlüsselpaar generieren (Sender)");
using MLDsa senderKey = MLDsa.GenerateKey(MLDsaAlgorithm.MLDsa87);
Console.WriteLine($"Algorithmus: {MLDsaAlgorithm.MLDsa87} (höchste Sicherheitsstufe)");
// Export öffentlicher Schlüssel als PEM
string publicKeyPem = senderKey.ExportSubjectPublicKeyInfoPem();
Console.WriteLine($"Öffentlicher Schlüssel (PEM): {publicKeyPem.Substring(0, Math.Min(80, publicKeyPem.Length))}...");
// 2. Sender signiert die Daten
CUI.H2("2. Daten signieren (Sender)");
byte[] signature = senderKey.SignData(data);
Console.WriteLine($"Signatur Größe: {signature.Length} Bytes");
Console.WriteLine($"Signatur: {Convert.ToHexString(signature).Substring(0, Math.Min(100, Convert.ToHexString(signature).Length))}...");
// 3. Empfänger importiert öffentlichen Schlüssel
CUI.H2("3. Öffentlichen Schlüssel importieren (Empfänger)");
using MLDsa verifierKey = MLDsa.ImportFromPem(publicKeyPem);
Console.WriteLine("Öffentlicher Schlüssel erfolgreich importiert");
// 4. Empfänger verifiziert die Signatur
CUI.H2("4. Signatur verifizieren (Empfänger)");
bool isValid = verifierKey.VerifyData(data, signature);
if (isValid)
{
CUI.Success("✓ Signatur ist gültig! Datenintegrität bestätigt.");
}
else
{
CUI.Error("✗ Signatur ist ungültig! Daten wurden möglicherweise manipuliert.");
}
// 5. Manipulationsversuch demonstrieren
CUI.H2("5. Manipulationsversuch demonstrieren");
byte[] manipulatedData = System.Text.Encoding.UTF8.GetBytes(originalText + " MANIPULIERT!");
bool isManipulatedValid = verifierKey.VerifyData(manipulatedData, signature);
if (!isManipulatedValid)
{
CUI.Warning("✓ Manipulation wurde erkannt! Signatur ist für geänderte Daten ungültig.");
}
else
{
CUI.Error("✗ FEHLER: Manipulation wurde nicht erkannt!");
}
}
catch (Exception ex)
{
CUI.Error(ex);
}
}
Der Screenshot zeigt die Ausgabe des Beispielcodes (Abb. 1).
(rme)