---
title: 'Anahtar Değişimi'
source: 'https://academia.sh/tr/kurslar/kimlik-ve-kriptografi/anahtar-degisimi'
course: 'Kimlik, Erişim ve Kriptografi'
language: tr
updated: '2026-08-17T18:08:37+00:00'
license: 'CC BY-SA 4.0'
---

# 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ı.

Ö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.

```js
// 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.

```js
// 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.
