Post-Quantum Kriptografi: ML-KEM, ML-DSA, SLH-DSA, Hybrid Yaklaşım ve Crypto Agility
Uzun süre gizli kalması gereken veri bugün kaydedilip kuantum bilgisayarla sonra çözülebileceği için RSA ve ECC'ye dayanan key exchange'i şimdiden hybrid ML-KEM'e taşımak gerekir; AES ve SHA-2 bu geçişin dışındadır. NIST IR 8547'nin 2030/2035 takvimini, .NET 10'un MLKem, MLDsa, SlhDsa ve CompositeMLDsa API'lerini, OpenSSL 3.5 ile gelen X25519MLKEM768 TLS grubunu ve Bookstore'un hybrid sipariş envelope'unu gerçek çıktılarla gösteriyoruz.
Sürüm notu: Bu yazıdaki kodlar .NET 10 ve xUnit v3 4.0 ile derlenip denenmiştir; çıktılar Ubuntu 24.04 (OpenSSL 3.0) ve Alpine 3.24 (OpenSSL 3.5) container'larında alınmıştır.
Önce Tahmin Et
Sitedeki serilerin ortak örnek uygulaması Bookstore (bir online kitapçı), tedarikçilere gönderdiği satın alma siparişlerini dördüncü yazıda kurduğumuz yöntemle şifreliyor: geçici bir ECDH (Elliptic Curve Diffie-Hellman; eliptik eğri üzerinde anahtar anlaşması) anahtarı, HKDF (HMAC tabanlı anahtar türetme fonksiyonu) ve AES (standart blok şifre) ile GCM (Galois/Counter Mode; kimlik doğrulamalı şifreleme modu) modunda şifreleme. Siparişlerde indirim oranları ve yıllık sözleşme hacimleri var; bu bilgiler on yıl sonra da gizli kalmalı. Bugün bu şifreyi kırabilecek bir kuantum bilgisayar yok. Öyleyse geçişi kuantum bilgisayar gelince yapmak yeterli mi?
Yeterli değil. Ağdaki birinin şifreli siparişleri bugün kaydedip, ECDH'yi kırabilecek bir makine çıktığında açması mümkün. Bu tehdidin adı "harvest now, decrypt later", yani şimdi topla, sonra çöz; NIST'in (ABD Ulusal Standartlar ve Teknoloji Enstitüsü) geçiş raporu da gizliliği uzun süre korunması gereken verinin bu yüzden bugünden risk altında olduğunu söylüyor. Bu yazıda hangi algoritmaların etkilendiğini, NIST'in yeni standartlarını, .NET 10'daki karşılıklarını, TLS'teki (HTTPS'in altındaki şifreli bağlantı protokolü) hybrid key exchange'i ve bir sonraki algoritma değişikliğini ucuzlatacak crypto agility'yi (algoritmayı kod yeniden yazmadan değiştirebilme) Bookstore üzerinde görüyoruz.
Tehdit: Hangi Algoritmalar Etkileniyor?
Yeterince büyük bir kuantum bilgisayarda çalışan Shor algoritması, RSA'nın (en yaygın public key algoritması) dayandığı çarpanlara ayırma problemini ve elliptic curve algoritmalarının dayandığı ayrık logaritma problemini verimli biçimde çözüyor. Bu, serideki bütün asymmetric yapıların etkilendiği anlamına geliyor: RSA-OAEP ile şifreleme, ECDH ile key agreement, RSA-PSS ve ECDSA (elliptic curve tabanlı imza algoritması) ile imza. Symmetric tarafta durum çok daha iyi. NIST IR (Interagency Report; NIST'in kurumlar arası raporu) 8547'ye göre en az 128 bit klasik güvenlik veren onaylı symmetric primitive'ler, yani AES, SHA (Secure Hash Algorithm; standart hash algoritmalarının ortak adı) ailesinden SHA-2 ve SHA-3, HMAC ve HKDF, kuantum saldırılarına karşı da yeterli kabul ediliyor ve NIST bunlardan geçiş beklemiyor. Bookstore'un AES-256-GCM ile şifrelenen telefon alanı ve HMAC ile imzalanan webhook'ları bu geçişin dışında.
Yerine gelen algoritmalar Ağustos 2024'te yayımlandı: FIPS (Federal Information Processing Standards; ABD federal kripto standartları) 203 key encapsulation algoritmasını (ML-KEM; modül kafes tabanlı anahtar kapsülleme), FIPS 204 bir imza algoritmasını (ML-DSA; modül kafes tabanlı imza), FIPS 205 de hash tabanlı bir imza algoritmasını (SLH-DSA; durumsuz, hash tabanlı imza) tanımlıyor. İlk ikisi lattice (kafes) problemlerine, SLH-DSA ise yalnız hash fonksiyonlarının güvenliğine dayanıyor; daha yavaş ve imzası büyük, ama varsayımı daha muhafazakâr.
NIST'in Takvimi
NIST IR 8547'nin final sürümü 27 Ekim 2026'da yayımlandı. Rapora göre NIST, kuantuma karşı savunmasız public key algoritmalarını, yani RSA, ECDSA, EdDSA ve finite field ile elliptic curve Diffie-Hellman'ı, 2030'dan sonra deprecated sayacak, 2035'ten sonra da kendi standartları altında kullanımına izin vermeyecek. Bu, daha önceki bir planı da değiştiriyor: SP (Special Publication; NIST'in özel yayın dizisi) 800-57, 112 bit güvenlik veren public key şemalarının (RSA-2048 gibi) 1 Ocak 2031'de yasaklanacağını öngörüyordu. Rapor bunun yerine bütün kuantuma açık imza algoritmalarının 2030'dan sonra deprecated olacağını, 2035'ten sonra yasaklanacağını söylüyor. Aynı rapor ABD federal kurumlarının en hassas sistemleri için daha erken tarihlerden de bahsediyor. Senin için pratik sonuç: 2030 uzak değil ve yazdığın kod muhtemelen o tarihten sonra da çalışacak.
.NET 10'da ML-KEM, ML-DSA ve SLH-DSA
.NET 10 bu üç algoritmayı MLKem, MLDsa ve SlhDsa class'larıyla getirdi. Serinin ilk yazısında gördüğümüz provider modeli burada en net hâliyle karşımıza çıkıyor: Microsoft Learn'e göre bu algoritmalar Linux'ta OpenSSL 3.5 ve sonrası, Windows'ta ise PQC (post-quantum cryptography; kuantum sonrası kriptografi) destekli CNG (Windows'un kripto kütüphanesi) gerektiriyor; Learn'deki platform tablosu Windows sütununda Ağustos 2026 itibarıyla "Windows 11 Insiders (Latest)" yazıyor. Aynı lab komutunu iki container'da çalıştırdım:
$ dotnet run --project src/Bookstore.CryptoLab -- pqc-sizes
Ubuntu 24.04.5 LTS, OpenSSL 3.0.13
algorithm public key signature / ciphertext
ECDSA P-256 (SPKI) 91 B 64 B
RSA-3072 (SPKI) 422 B 384 B
ML-KEM: False, ML-DSA: False, SLH-DSA: False -> post-quantum algorithms need OpenSSL 3.5+ or Windows CNG with PQC
$ docker run --rm -v "${PWD}:/src/bookstore" -w /src/bookstore mcr.microsoft.com/dotnet/runtime:10.0-alpine dotnet src/Bookstore.CryptoLab/bin/Debug/net10.0/Bookstore.CryptoLab.dll pqc-sizes
Alpine Linux v3.24, OpenSSL 3.5.9
algorithm public key signature / ciphertext
ECDSA P-256 (SPKI) 91 B 64 B
RSA-3072 (SPKI) 422 B 384 B
ML-KEM-512 800 B 768 B secret 32 B, same on both sides: True
ML-KEM-768 1184 B 1088 B secret 32 B, same on both sides: True
ML-KEM-1024 1568 B 1568 B secret 32 B, same on both sides: True
ML-DSA-44 1312 B 2420 B verify: True
ML-DSA-65 1952 B 3309 B verify: True
ML-DSA-87 2592 B 4627 B verify: True
SLH-DSA-SHA2-128s 32 B 7856 B verify: True
SLH-DSA-SHA2-128f 32 B 17088 B verify: True
MLDSA65-ECDSA-P256-SHA512 2017 B 3379 B verify: True, ECDSA part tampered: False
İlk dikkat çeken şey boyutlar. ML-KEM-768'in public key'i 1184 byte, ciphertext'i 1088 byte; P-256'nın 91 byte'lık public key'iyle karşılaştır. ML-DSA-65 imzası 3309 byte, ECDSA'nın 64 byte'ının elli katından fazla. SLH-DSA'nın public key'i yalnız 32 byte ama imzası 7856 ile 17088 byte arasında; "s" (small) parametresi küçük ama yavaş imza, "f" (fast) parametresi hızlı ama büyük imza veriyor. Bir JWT'nin (JSON Web Token; imzalı token biçimi), bir sertifika zincirinin ya da her istekte gönderilen bir imzanın bu kadar büyümesi, header limitlerine, cookie boyutlarına ve bant genişliğine dokunuyor.
İkincisi API'nin olgunluğu. MLKem stabil bir tip, ama SPKI (SubjectPublicKeyInfo; public key'in standart ikili yapısı) import ve export method'ları [Experimental]. MLDsa, SlhDsa ve CompositeMLDsa ise tamamen deneysel ve kullanmak için SYSLIB5006 uyarısını bilerek kapatman gerekiyor; kapatmadığında derleme şu hatayla duruyor:
error SYSLIB5006: 'System.Security.Cryptography.SlhDsaAlgorithm' is for evaluation purposes only and is subject to change or removal in future updates. Suppress this diagnostic to proceed.
Lab'da bunu dosya düzeyinde bir #pragma warning disable SYSLIB5006 ile yaptık. Production kodunda bu tipleri doğrudan her yere dağıtma; kendi küçük arayüzünün arkasına koy, API değiştiğinde tek bir yeri güncelle.
Hybrid İmza: Composite ML-DSA
Yeni algoritmalar on yıllardır incelenen RSA ve ECC (eliptik eğri kriptografisi) kadar sınanmış değil. Bu yüzden geçiş döneminde yaygın yaklaşım hybrid: klasik ve post-quantum algoritmayı birlikte kullanmak, biri kırılsa bile diğeri korusun. İmza tarafında bunun .NET karşılığı CompositeMLDsa; IETF (Internet Engineering Task Force; internet standartlarını yazan kuruluş) taslağındaki composite imzaları uyguluyor. Çıktının son satırındaki MLDSA65-ECDSA-P256-SHA512 bir ML-DSA-65 ve bir ECDSA P-256 imzasını tek imza olarak taşıyor: 3379 byte, yani 3309 + ECDSA'nın DER (sertifikalardaki yapıların standart ikili kodlaması) ile kodlanmış imzası. İmzanın son byte'ını, yani yalnız ECDSA yarısını bozduğumda doğrulama False döndü: iki yarının da geçmesi gerekiyor.
TLS'te Hybrid Key Exchange
Harvest now, decrypt later tehdidi en çok TLS trafiğini ilgilendiriyor, çünkü kaydedilmesi en kolay veri o. TLS 1.3'te hybrid key exchange için tanımlanan grup X25519MLKEM768: X25519 (Curve25519 üzerinde tanımlı key agreement) ve ML-KEM-768'in key share'leri tek bir key share içinde gidiyor, iki ortak sır da key schedule'a giriyor. IANA (Internet Assigned Numbers Authority; protokol numaralarını yöneten kuruluş) kayıt defterinde 4588 numarasıyla ve önerilen olarak işaretli. Networking ve HTTP serisinin TLS 1.3 handshake yazısında post-quantum key exchange'e girişi yapmıştık; şimdi .NET'in kendisi ne gönderiyor, ona bakalım. tls-groups komutu önceki yazıdaki loopback bağlantısını kuruyor ve ClientHello ile ServerHello'nun ilgili extension'larını okuyor:
$ dotnet run --project src/Bookstore.CryptoLab -- tls-groups
Ubuntu 24.04.5 LTS, OpenSSL 3.0.13
ClientHello supported_groups: x25519, secp256r1, x448, secp521r1, secp384r1, ffdhe2048, ffdhe3072, ffdhe4096, ffdhe6144, ffdhe8192
ClientHello key_share : x25519 (32 B)
ServerHello key_share : x25519 (32 B)
negotiated : Tls13, TLS_AES_256_GCM_SHA384
Alpine Linux v3.24, OpenSSL 3.5.9
ClientHello supported_groups: X25519MLKEM768, x25519, secp256r1, x448, secp384r1, secp521r1, ffdhe2048, ffdhe3072
ClientHello key_share : X25519MLKEM768 (1216 B), x25519 (32 B)
ServerHello key_share : X25519MLKEM768 (1120 B)
negotiated : Tls13, TLS_AES_256_GCM_SHA384
Kodun tek satırı değişmedi; değişen yalnız base image ve onunla gelen OpenSSL sürümü. OpenSSL 3.5 ile SslStream hybrid grubu ilk sıraya koyuyor ve iki tarafı da OpenSSL 3.5 olan bağlantı onunla kuruluyor. Key share 32 byte'tan 1216 byte'a çıkıyor: 32 byte X25519 ve 1184 byte ML-KEM-768 public key'i. Bunun pratik anlamı şu: TLS'i post-quantum yapmak bir .NET kod değişikliği değil, bir platform güncellemesi. Container image'ının OpenSSL sürümü, Windows sunucunun Schannel desteği ve önündeki reverse proxy ya da load balancer'ın TLS kütüphanesi asıl karar noktaları. Windows'ta Schannel'ın bu grubu sunup sunmadığını bu yazı için doğrulamadım.
Bookstore'un Sipariş Dosyası: Hybrid Envelope
Uygulama seviyesinde şifrelediğimiz veri için ise kod değişikliği gerekiyor. Dördüncü yazıdaki envelope'un yanına hybrid bir sürüm ekledik: ML-KEM-768 ile key encapsulation ve geçici ECDH P-256, iki ortak sır birlikte HKDF'ten geçiyor. Saldırganın anahtarı öğrenmesi için ikisini birden kırması gerekiyor:
recipientKem.Encapsulate(out byte[] kemCiphertext, out byte[] kemSecret);
using ECDiffieHellman ephemeral = ECDiffieHellman.Create(ECCurve.NamedCurves.nistP256);
byte[] ephemeralPublic = ephemeral.ExportSubjectPublicKeyInfo();
byte[] ecdhSecret = ephemeral.DeriveRawSecretAgreement(recipientEcdh.PublicKey);
// Kapsüllenmiş anahtar = ML-KEM ciphertext'i (sabit boyut) | geçici ECDH public key'i
byte[] encapsulated = [.. kemCiphertext, .. ephemeralPublic];
byte[] key = DeriveKey(kemSecret, ecdhSecret, encapsulated, keyId);
// İki sır da giriyor, iki ciphertext de salt: anahtarı öğrenmek için ML-KEM'i de ECDH'yi de kırmak gerekir
private static byte[] DeriveKey(byte[] kemSecret, byte[] ecdhSecret, byte[] encapsulated, string keyId) =>
HKDF.DeriveKey(HashAlgorithmName.SHA256, [.. kemSecret, .. ecdhSecret], 32, salt: encapsulated,
info: Encoding.UTF8.GetBytes($"bookstore/purchase-order/v2|{Algorithm}|{keyId}"));
Bu, TLS'teki hybrid grubun mantığıyla aynı: sırları uç uca ekleyip bir KDF'ten (key derivation function; anahtar türetme fonksiyonu) geçirmek. Algoritma adı info'ya da giriyor; böylece aynı sırlarla başka bir algoritma adı altında aynı anahtar türetilemiyor. Komut aynı siparişi iki yöntemle şifreliyor ve tedarikçi tarafında okuyor:
$ dotnet src/Bookstore.CryptoLab/bin/Debug/net10.0/Bookstore.CryptoLab.dll pqc-envelope
ECDH-P256.HKDF-SHA256.A256GCM 473 B JSON, decrypted: {"purchaseOrder":"PO-2026-11-0042"...
MLKEM768+ECDH-P256.HKDF-SHA256.A256GCM 1940 B JSON, decrypted: {"purchaseOrder":"PO-2026-11-0042"...
hybrid relabelled as classic: CryptographicException: Unsupported envelope: v2 ECDH-P256.HKDF-SHA256.A256GCM
unknown algorithm: CryptographicException: Algorithm not accepted: MLKEM512.A128GCM
ML-KEM part of the key replaced: AuthenticationTagMismatchException: The computed authentication tag did not match the input authentication tag.
Aynı sipariş 473 byte'tan 1940 byte'a çıktı; büyük kısmı ML-KEM ciphertext'i. Hybrid envelope'u klasik olarak etiketleyip daha zayıf yola yönlendirme denemesi reddediliyor, listede olmayan bir algoritma kabul edilmiyor, ML-KEM anahtarı yanlış olduğunda ECDH yarısı doğru olsa bile AES-GCM tag'i tutmuyor.
Crypto Agility
Bu geçişi mümkün kılan şey, seri boyunca formatlarımıza koyduğumuz küçük alanlar: alan şifrelemesindeki sürüm byte'ı ve keyId, lisanstaki BSL1 öneki ve keyId, envelope'taki Algorithm alanı. Crypto agility, algoritmayı değiştirmenin bir veri migrasyonu ve bir config değişikliği olması, yeniden yazılım projesi olmaması demek. Okuyucu tarafı tek bir yerde, bir izin listesine göre karar veriyor:
public static byte[] Open(RecipientKeys keys, HybridEnvelope envelope)
{
if (!Accepted.Contains(envelope.Algorithm))
{
throw new CryptographicException($"Algorithm not accepted: {envelope.Algorithm}");
}
return envelope.Algorithm switch
{
PqHybrid.Algorithm => PqHybrid.Decrypt(keys.Kem ?? throw new CryptographicException("No ML-KEM key."), keys.Ecdh, envelope),
EcdhHybrid.Algorithm => EcdhHybrid.Decrypt(keys.Ecdh, envelope),
RsaHybrid.Algorithm => RsaHybrid.Decrypt(keys.Rsa ?? throw new CryptographicException("No RSA key."), envelope),
_ => throw new CryptographicException($"Algorithm not accepted: {envelope.Algorithm}"),
};
}
Algoritma veriden okunuyor ama kararı veri vermiyor: izin listesi ve her algoritmanın kendi sürüm kontrolü kodda. Eski algoritmalar listede yalnız okuma için duruyor; yazma yolu her zaman güncel algoritmayı kullanıyor ve eski kayıtlar arka planda yeniden şifreleniyor.
Agility'nin ikinci ayağı envanter: hangi serviste hangi algoritmanın, hangi anahtar boyutunun ve hangi kütüphanenin kullanıldığını bilmeden neyi taşıyacağına karar veremezsin. CycloneDX 1.7 (Ekim 2025) bunun için CBOM (Cryptography Bill of Materials; yazılımdaki kripto varlıklarının listesi) desteğini algoritma aileleri kataloğu ve eliptik eğri listesiyle genişletti; SBOM (Software Bill of Materials; yazılımdaki bileşenlerin listesi) ve CBOM üretimi DevSecOps serisinin SBOM yazısında. Bookstore'da öncelik sırası şöyle: önce gizliliği uzun süre korunması gereken ve bugün kaydedilebilen veri, yani tedarikçi siparişleri ve servisler arası TLS. TLS için platformu güncelliyoruz, siparişler için hybrid envelope'a geçiyoruz. İmzalar sonra geliyor: bir imza sahteciliği ancak kuantum bilgisayar var olduğunda mümkün olacağı için lisans anahtarlarını 2030'a kadar composite imzaya taşımak yeterli. AES-GCM ile alan şifrelemesine ve HMAC'li webhook'lara dokunmuyoruz.
Üretimde Dikkat
Platform desteğini açılışta kontrol et. Serinin ilk yazısındaki CryptoRequirements yaklaşımı burada da geçerli: hybrid envelope'u yazma yolunda kullanan bir servis ML-KEM'i olmayan bir image'da açılmamalı, ilk siparişte değil. Ubuntu 24.04 tabanlı bir image'ı "küçük olsun" diye Alpine'a ya da tersine çevirmek kripto yeteneğini de değiştiriyor.
Testlerin de platforma bağlı. ML-KEM testlerimiz Assert.SkipUnless(MLKem.IsSupported, ...) ile korunuyor; Ubuntu 24.04'te dotnet test 66 testten 3'ünü atlıyor. Aynı test binary'sini Alpine 3.24'te çalıştırdığımda 66 testin hepsi geçti. CI'da en az bir job'ı PQC destekli bir platformda çalıştır; yoksa atlanan testler hiç çalışmayan testlere dönüşür.
Boyut artışını ölç. 1.2 KB büyüyen bir ClientHello eski bazı ara cihazlarda sorun çıkarabiliyor, ML-DSA imzalı bir JWT header limitlerine takılabiliyor, sipariş dosyası dört katına çıkıyor. Geçişten önce bu sınırları kendi ortamında dene.
Sık Düşülen Tuzaklar
Birinci tuzak, Önce Tahmin Et'teki: geçişi kuantum bilgisayarın geldiği güne bırakmak. Uzun süre gizli kalması gereken veri için tehdit, kaydedildiği gün başlıyor.
İkincisi, symmetric kriptoyu da değiştirmeye çalışmak. AES-256, SHA-256 ve HMAC için geçiş gerekmiyor; çabayı asymmetric tarafa ver.
Üçüncüsü, tek başına yeni algoritmaya geçmek. Hybrid yaklaşım, yeni algoritmalarda ileride bulunabilecek bir zayıflığa karşı sigorta; geçiş döneminde klasik algoritmayı bırakma.
Dördüncüsü, sırları birleştirirken kısayol almak: iki ortak sırrı XOR'lamak (bit bit dışlayan veya ile birleştirmek) ya da yalnız birini KDF'e vermek. İkisini de, ciphertext'leriyle birlikte bir KDF'ten geçir.
Beşincisi, deneysel API'leri kodun her yerine yaymak. SYSLIB5006'yı projede genel olarak kapatmak, API değiştiğinde nerelerin etkilendiğini görmeni zorlaştırır; uyarıyı yalnız sarmalayıcı class'ında kapat.
Küçük Bir Deneme
★☆☆ pqc-sizes komutuna SlhDsaShake256f ve MLDsa87WithECDsaP384 satırlarını ekle. Hangisinin imzası daha büyük?
★★☆ Bookstore'un lisans formatına BSL2 sürümünü ekle: CompositeMLDsa (MLDsa65WithECDsaP256) ile imzalansın; doğrulayıcı BSL1'i kabul etmeye devam etsin. Lisans metni kaç karaktere çıkıyor? Bunu bir karekod (QR) ya da e-posta eki için değerlendir.
★★★ CryptoRequirements'a "yazma yolu algoritmaları" kavramını ekle: PqHybrid.Algorithm yazma için gerekiyorsa ve MLKem.IsSupported false ise uygulama açılışta dursun. Ubuntu ve Alpine image'larında ayrı ayrı dene.
Bu yazıda .NET 10'un post-quantum API'lerini ve geçişin planını gördük. Serinin son yazısında geriye ve ileriye bakıyoruz: .NET Framework'ten kalan eski kripto kodunu okumak, obsolete tipler ve uyarıları, ve .NET 11 ile gelen X25519, HPKE (Hybrid Public Key Encryption; standartlaşmış hybrid şifreleme şeması) ve composite ML-KEM.