Ders 06 / 21
Anahtar Değişimi
Güvensiz kanalda ortak sır üretiminin küçük parametrelerle koşturulması: iki tarafın gizli üssünü hiç göndermeden aynı ortak sırra ulaşması, kanalda geçen 4 kalem ile sırra yeten 3 kalemin kesişiminin sıfır olması, geçici anahtar değişiminin geçmişe dönük açılan oturum sayısını 52.560'tan 0'a indirmesi ve değişimin üç kaleminden ikisini doğrulayıp karşı tarafın kimliğini doğrulamaması.
İçindekiler
Önceki dersteki melez yol anahtarı taşıdı ama taşınan anahtarı gönderen taraf seçti. Bunun iki sonucu vardı. Birincisi, oturum anahtarının kalitesi tümüyle o tarafın üretecine bağlıydı. İkincisi ve daha ağırı: kaydedilmiş şifreli trafik saklanabilir ve özel anahtar yıllar sonra sızarsa, o güne kadarki bütün oturum anahtarları zarflardan geri çıkarılır.
Bu ders ikisini birden ortadan kaldıran yöntemi ele alır. İki taraf, gizli değerlerini hiç göndermeden aynı ortak sırra ulaşır; ortak sır kanaldan geçmez ve hiçbir taraf onu tek başına belirlemez. Yöntem küçük parametrelerle gerçekten koşturulacak, sonra dinleyicinin elinde kalan kalemler tek tek sayılacak.
Kanaldan Geçmeyen Sır
KT17: iki taraf, gizli üssünü hiç göndermeden ortak bir sır üretebilir; kanaldan geçen kalemler ile ortak sır arasında doğrudan bir hesap yolu yoktur.
KT18: ortak sır iki tarafın katkısıyla oluşur; hiçbir taraf onu tek başına belirlemez.
Yöntem şudur. Taraflar bir asal p ve bir üreteç g üzerinde açıkça anlaşır. Her taraf gizli
bir üs seçer, g üssünü p modunda hesaplar ve sonucu karşıya gönderir. Karşıdan gelen
değeri kendi gizli üssüyle yeniden üsse alan iki taraf da aynı değere iner, çünkü üs alma
sırasından bağımsızdır. Aşağıdaki parametreler öğretim boyutundadır ve gerçek bir kurulumda
kullanılmaz.
// degisim/dh.mjs — anahtar degisimi kucuk parametrelerle gercekten kosturulur. p ve g // ogretim icin secilmis kucuk kurgu degerlerdir; gercek kurulumda kullanilmaz. Ozel // usler sabittir ki cikti kosumdan kosuma ayni kalsin. Rastgelelik yok. import { hkdfSync, createCipheriv, createDecipheriv } from "node:crypto"; // KT17: iki taraf, gizli usunu hic gondermeden ortak bir sir uretebilir; kanaldan gecen // kalemler ile ortak sir arasinda dogrudan bir hesap yolu yoktur. // KT18: ortak sir iki tarafin katkisiyla olusur; hicbir taraf onu tek basina belirlemez. const p = 65267n, g = 2n; // kurgu, ogretim boyutunda asal ve uretec const usal = (t, u, m) => { let r = 1n; t %= m; while (u > 0n) { if (u & 1n) r = r * t % m; t = t * t % m; u >>= 1n; } return r; }; const a = 6421n, b = 8973n; // kurgu gizli usler: sube ve merkez const A = usal(g, a, p), B = usal(g, b, p); // kanaldan gecen genel degerler const subeSir = usal(B, a, p), merkezSir = usal(A, b, p); console.log(`kanaldan gecen kalemler : p=${p} g=${g} A=${A} B=${B}`); console.log("kanaldan gecmeyen kalem : a ve b (iki gizli us)"); console.log("sube ortak sir :", String(subeSir)); console.log("merkez ortak sir :", String(merkezSir)); console.log("iki taraf ayni sirri mi uretti:", subeSir === merkezSir ? "evet" : "hayir"); console.log("ortak sir kanaldan gecti mi :", [p, g, A, B].includes(subeSir) ? "evet" : "hayir"); // Ortak sir dogrudan anahtar olarak kullanilmaz; anahtar turetme ile sabit boya cekilir. const ham = Buffer.from(subeSir.toString(16).padStart(4, "0"), "hex"); const anahtar = Buffer.from(hkdfSync("sha256", ham, Buffer.alloc(16, 9), "olcum-agi-oturum", 32)); const nonce = Buffer.alloc(12, 4), OKUMA = "SAY-4417|2026-03-01T06:00Z|41982"; const s = createCipheriv("aes-256-gcm", anahtar, nonce); const govde = Buffer.concat([s.update(OKUMA, "utf8"), s.final()]), etiket = s.getAuthTag(); const c = createDecipheriv("aes-256-gcm", Buffer.from(hkdfSync("sha256", Buffer.from(merkezSir.toString(16).padStart(4, "0"), "hex"), Buffer.alloc(16, 9), "olcum-agi-oturum", 32)), nonce); c.setAuthTag(etiket); console.log("turetilen anahtar boyu :", anahtar.length, "bayt"); console.log("merkez, sube paketini cozdu :", Buffer.concat([c.update(govde), c.final()]).toString() === OKUMA ? "evet" : "hayir");
kanaldan gecen kalemler : p=65267 g=2 A=10224 B=40077 kanaldan gecmeyen kalem : a ve b (iki gizli us) sube ortak sir : 41173 merkez ortak sir : 41173 iki taraf ayni sirri mi uretti: evet ortak sir kanaldan gecti mi : hayir turetilen anahtar boyu : 32 bayt merkez, sube paketini cozdu : evet
Beşinci satır yöntemin tamamıdır: şube 41173’e, merkez de 41173’e ulaştı ve bu değer hiçbir zaman gönderilmedi. Kanaldan yalnız 65267, 2, 10224 ve 40077 geçti.
Son iki satır ortak sırrın nasıl kullanıldığını gösterir. Ham ortak sır doğrudan anahtar olarak kullanılmaz — sayısal bir değerdir, uzunluğu parametreye bağlıdır ve dağılımı bir anahtardan beklenen dağılım değildir. Anahtar türetme işlemi onu sabit boyda, düzgün dağılmış bir anahtara çevirir. Türetilen anahtarla şifrelenen paketi karşı taraf kendi ortak sırrından türettiği anahtarla çözebiliyor; zincir uçtan uca çalışıyor.
Dinleyicinin Elindeki Kalemler
Yöntemin dayandığı şey, g^a mod p değerinden a değerine dönmenin — kısaca kesikli
logaritmanın — pahalı olmasıdır. Aşağıdaki sayım bunu kalem kalem yazar.
// degisim/kalem.mjs — anahtar degisiminin kalem sayimi (model): dinleyicinin elindeki // kalemler, parametre boyu ile aday us sayisi, gecmise donuk acilan oturum sayisi ve // dogrulanan kalem sayisi. Kurgu bolgesel olcum agi sayilari kullanilir. // KT19: anahtar degisimi ortak sirri uretir ama karsi tarafin kimligini dogrulamaz; // dogrulanmayan bir degisimde iki taraf ayri ayri iki sir uzerinde anlasabilir. const yaz = (g, ...s) => console.log(s.map((v, i) => (g[i] < 0 ? String(v).padEnd(-g[i]) : String(v).padStart(g[i]))).join("")); console.log("dinleyicinin elindeki kalemler:"); const A = [-26, 10, 12]; yaz(A, "kalem", "kanalda", "sirra yeter"); for (const [ad, kanal, yeter] of [ ["asal p", "evet", "hayir"], ["uretec g", "evet", "hayir"], ["subenin genel degeri A", "evet", "hayir"], ["merkezin genel degeri B", "evet", "hayir"], ["subenin gizli usu a", "hayir", "evet"], ["merkezin gizli usu b", "hayir", "evet"], ["ortak sir", "hayir", "evet"], ]) yaz(A, ad, kanal, yeter); console.log("kanalda gecen kalem 4, sirra yeten kalem 3, ikisinin kesisimi 0"); console.log("\naday us sayisi parametre boyuyla:"); const B = [10, 20, 18]; yaz(B, "p biti", "aday us", "kurgu agda sinama"); for (const bit of [16, 32, 64, 2048]) yaz(B, bit, bit <= 32 ? (2 ** bit).toLocaleString("tr-TR") : "2^" + bit, bit <= 32 ? "sayilabilir" : "sayilamaz"); const SUBE = 6, OTURUM = 24 * 365; // kurgu: sube basina saatlik oturum console.log(`\ngecmise donuk acilma (kurgu ${SUBE} sube, sube basina ${OTURUM} oturum/yil):`); const C = [-24, -16, 16]; yaz(C, "duzen", "sirri belirleyen", "acilan oturum"); yaz(C, "asimetrik zarfla tasima", "gonderen taraf", (SUBE * OTURUM).toLocaleString("tr-TR")); yaz(C, "gecici anahtar degisimi", "iki taraf birden", 0); console.log("\ndegisimin dogruladigi kalem:"); const D = [-32, 13]; yaz(D, "kalem", "dogrulaniyor"); for (const [ad, d] of [["ortak sirrin gizliligi", "evet"], ["iki tarafin ayni sirri uretmesi", "evet"], ["karsi tarafin kimligi", "hayir"]]) yaz(D, ad, d); console.log("3 kalemden 2'si dogrulaniyor; dogrulanmayan kalem araya giren bir tarafin"); console.log("iki ayri degisim yurutmesine kapiyi acik birakir (model, 2 ayri ortak sir).");
dinleyicinin elindeki kalemler:
kalem kanalda sirra yeter
asal p evet hayir
uretec g evet hayir
subenin genel degeri A evet hayir
merkezin genel degeri B evet hayir
subenin gizli usu a hayir evet
merkezin gizli usu b hayir evet
ortak sir hayir evet
kanalda gecen kalem 4, sirra yeten kalem 3, ikisinin kesisimi 0
aday us sayisi parametre boyuyla:
p biti aday us kurgu agda sinama
16 65.536 sayilabilir
32 4.294.967.296 sayilabilir
64 2^64 sayilamaz
2048 2^2048 sayilamaz
gecmise donuk acilma (kurgu 6 sube, sube basina 8760 oturum/yil):
duzen sirri belirleyen acilan oturum
asimetrik zarfla tasima gonderen taraf 52.560
gecici anahtar degisimi iki taraf birden 0
degisimin dogruladigi kalem:
kalem dogrulaniyor
ortak sirrin gizliligi evet
iki tarafin ayni sirri uretmesi evet
karsi tarafin kimligi hayir
3 kalemden 2'si dogrulaniyor; dogrulanmayan kalem araya giren bir tarafin
iki ayri degisim yurutmesine kapiyi acik birakir (model, 2 ayri ortak sir).
Birinci tablonun son satırı yöntemin özüdür: kanalda geçen dört kalem ile sırra yeten üç kalemin kesişimi sıfırdır. Dinleyici dört kalemi de kaydeder ve hiçbiri onu üçüncü kümeye taşımaz. “Dinleyici sırra ulaşamaz” ifadesinin sayısal karşılığı budur.
İkinci tablo bu ayrımın neye bağlı olduğunu gösterir. Kanalda geçen kalemlerden gizli üsse dönmek imkânsız değildir — yalnızca pahalıdır ve pahalılık parametre boyuyla belirlenir. Bu dersteki 16 bitlik asal için aday üs sayısı 65.536’dır ve bu, sıradan bir makinede sayılabilir bir kümedir. Öğretim parametresi olarak seçilmesinin nedeni budur; koşan örnek küçük olduğu için hızlıdır, güvenli olduğu için değil. Gerçek kurulumlarda kullanılan boy 2048 bit ve üzeridir; oradaki aday sayısı 2^2048’dir.
Aynı yöntem, üs alma yerine eliptik eğri üzerinde tanımlanmış bir işlemle de kurulur ve mantığı değişmez: her taraf bir gizli değer seçer, karşılığını gönderir, karşıdan geleni kendi gizli değeriyle işler. Değişen tek şey aynı güvenlik için gereken parametre boyudur. Önceki dersteki tabloya göre 3072 bitlik bir asalın eşdeğeri 256 bitlik bir eğri parametresidir; yani her turda taşınan genel değer 384 bayt yerine 32 bayta iner.
Kurgu ölçüm ağında bu fark doğrudan trafiğe yazılır. Günde 297.600 tur, tur başına 384 bayt genel değer taşırsa günlük yük yaklaşık 109 MiB’dir; 32 baytlık genel değerle aynı yük 9,1 MiB’ye iner. On iki kat fark, kısıtlı uçlarda değişimin yapılabilir olup olmamasını belirler.
İki Sonuç, İki Ayrı Sayı
Üçüncü tablo önceki dersin ikinci sorununu kapatır. Asimetrik zarfla anahtar taşındığında oturum anahtarını gönderen taraf belirler ve zarf, uzun ömürlü özel anahtarla açılır. Kayıtlı trafiği elinde tutan bir taraf o özel anahtara yıllar sonra ulaşırsa, kurgu ağdaki 52.560 oturumun tamamını açar; oturumların ne zaman yapıldığının hiçbir önemi yoktur.
Bu satırın altında yatan varsayım, şifreli trafiğin kaydedilebilmesidir. Kaydetmenin maliyeti düşüktür ve çözmenin maliyeti sonraya bırakılabilir; kurgu ağda bir yılın bütün oturumları birkaç yüz gigabaytlık bir arşive sığar. Bu yüzden “anahtar sızmadı” durumu bugünün sorusuyla değil, arşivin ömrüyle ölçülür.
Geçici anahtar değişiminde sayı sıfırdır. Her oturum için yeni gizli üsler seçilir, ortak sır o oturumla sınırlıdır ve oturum bittiğinde üsler silinir. Uzun ömürlü anahtarın sonradan sızması geçmişe dönük hiçbir oturumu açmaz, çünkü geçmiş oturumların sırrı hiçbir yerde saklanmamıştır. Bu özellik ileri gizlilik (forward secrecy) adını taşır ve bedeli her oturum için bir çift üs üretmek ile fazladan bir tur alışveriştir.
Zincirin Yedi Kalemi
Bu mekanizmanın kaç kalemi aynı anda doğru olmalı sorusunun yanıtı yedidir ve altısı mekanizmanın kendi içindedir.
Birincisi ve ikincisi parametrelerdir: p gerçekten asal ve yeterince büyük olmalı, g o
asalın uygun bir üreteci olmalıdır. Parametreler gizli değildir ve genellikle taraflarca
paylaşılan sabitlerdir; bu, onların denetlenmesini kolaylaştırır ama kusurlu bir parametre
kümesini de her oturuma taşır. Kötü seçilmiş bir asal, aday üs sayısını tablodaki 2^2048
değerinden çok daha küçük bir sayıya indirir ve bu, koşum sırasında hiçbir belirti üretmez —
değişim yine çalışır, yine aynı sırrı verir.
Üçüncü ve dördüncü kalemler iki gizli üstür. Beşinci kalem üslerin her oturumda yenilenmesidir; yenilenmediklerinde ileri gizlilik tablosundaki sıfır, oturum sayısına döner. Altıncı kalem türetme adımıdır: ham ortak sır anahtar olarak kullanılırsa dağılım bozuk kalır ve zincirin geri kalanı bu bozuk anahtarın üzerine kurulur.
Yedinci kalem mekanizmanın dışındadır ve bir sonraki bölümün konusudur. Altı kalemin altısı doğru olsa bile, karşı tarafın kim olduğu bu yöntemin içinde hiçbir biçimde belirlenmez.
Bedeli de sayılabilir. Değişim, bağlantı kurulumuna en az bir ek tur ekler ve iki tarafta da üs alma hesabı gerektirir. Kurgu ölçüm ağında 12.400 uç saatte bir oturum açarsa bu, günde 297.600 ek tur ve aynı sayıda üs alma işlemi demektir. Karşılığında elde edilen şey, üçüncü tablodaki 52.560 oturumun geçmişe dönük kapanmasıdır.
Doğrulanmayan Kalem
Dördüncü tablo bu dersin sınırıdır. Değişim üç kalemden ikisini doğruluyor: ortak sır gizli kalıyor ve iki taraf aynı sırrı üretiyor. Üçüncü kalem — karşı tarafın kimliği — doğrulanmıyor.
Sonucu sayıyla yazmak mümkündür. Değişimin iki ucu arasına giren bir taraf, iki ayrı değişim yürütebilir: bir tarafla bir ortak sır, öteki tarafla başka bir ortak sır. İki uç da doğru çalıştığını görür, çünkü ikisi de kendi tarafında geçerli bir sır üretmiştir. Doğrulanan kalem sayısı iki, açık kalan kalem sayısı bir ve ortaya çıkan ortak sır sayısı ikidir. Bu bir yapılandırma kusuru değildir; değişim yönteminin kapsamına kimlik girmez.
Parametre üzerinde anlaşmanın kendisi de aynı boşluğun içindedir. p ve g kanaldan açıkça
geçtiği için, iki tarafın hangi parametrelerde anlaştığı da doğrulanmamış bir kalemdir; araya
giren bir taraf, iki ucun da desteklediği en küçük parametre kümesini seçtirebilir ve tablodaki
2^2048 değeri sessizce 2^32’ye iner. Değişim yine tamamlanır, iki taraf yine aynı sırrı üretir
ve hiçbir belirti oluşmaz. Bu yüzden kurulumlarda kabul edilen en küçük parametre boyu bir
politika kalemi olarak ayrıca yazılır — anlaşmaya bırakılmaz.
Yöntemin adı da bu sınırı taşır: anahtar değişimi, kimlik doğrulaması değil. Kurgu ölçüm ağında bir şube ile merkez arasındaki değişim, karşı tarafın gerçekten merkez olduğunu söylemez — yalnızca kiminle konuşuluyorsa onunla bir sır paylaşıldığını söyler.
Özet
- İki taraf gizli üssünü hiç göndermeden aynı ortak sırra ulaşır: koşan örnekte iki taraf da 41173 değerine indi ve bu değer kanaldan hiç geçmedi.
- Kanalda geçen 4 kalem ile sırra yeten 3 kalemin kesişimi sıfırdır; dinleyici kaydettiği kalemlerden ortak sırra geçemez.
- Güvenlik parametre boyuna bağlıdır: 16 bitlik asalda aday üs sayısı 65.536’dır ve sayılabilir; öğretim örneği küçük olduğu için hızlıdır, güvenli olduğu için değil.
- Ham ortak sır doğrudan anahtar olarak kullanılmaz; anahtar türetmeyle sabit boyda ve düzgün dağılmış bir anahtara çevrilir.
- Geçici değişimde uzun ömürlü anahtarın sızması geçmişe dönük 0 oturum açar; asimetrik zarfla taşımada aynı sızıntı kurgu ağdaki 52.560 oturumun tamamını açar.
- Değişim üç kalemden ikisini doğrular; karşı tarafın kimliği doğrulanmaz ve doğrulanmayan bir değişimde iki ayrı ortak sır oluşabilir.
Sonraki Adım
Doğrulanmayan kalem bir adım daha geriye götürür. Karşı tarafın kimliğini değişimin kendisi veremiyorsa, dışarıdan bir kanıt gerekir ve o kanıt beşinci derste bir kez görülmüştü: özel anahtarla yapılan işlem, açık anahtarla geri alınıyor ve geri alınabilmesi kaynağı gösteriyordu. Sonraki ders bu yönü kendi biçimiyle ele alıyor — imza üretilip doğrulanıyor, imzalanan verinin tek bir biti çevrildiğinde doğrulamanın düştüğü sayılıyor ve imzanın kanıtladığı kalemler ile kanıtlamadığı kalemler ayrı ayrı yazılıyor. Bütünlük ile inkâr edilemezliğin farkı da orada sayıya bağlanıyor. Konu bu dersle kapanmıyor; asıl boşluk yedinci dersin sonunda ortaya çıkacak.
İlerlemeni kaydetmek ve not almak için Giriş yap
Notlarım
Not almak için giriş yapmalısın.