00Problem: neden bunlara ihtiyacımız var
İnternette iki bilgisayar konuşurken veri düz metin olarak gider. Kafede oturuyorsun, yanındaki adam aynı WiFi'da ve bankaya gönderdiğin şifreyi okuyabiliyor. Bu gerçek bir tehdit.
Çözmemiz gereken üç ayrı sorun var. Bunları karıştırmak, yanlış aracı uygulamak demektir:
TLS bu üç sorunu tek protokolde çözer. Ama TLS'i anlamak için önce altındaki yapı taşlarını bilmek lazım. Sırayla gidelim.
01Simetrik şifreleme
En basit fikirdir: bir anahtar var, bununla hem kilitlersin hem açarsın.
Sen ve arkadaşın ortak bir gizli kelime belirlediniz, diyelim kedi123. Sen mesajını bu kelimeyle şifrelersin, arkadaşın aynı kelimeyle çözer.
Orijinal mesaj: "Şifrem 1234" Anahtar: kedi123 Şifreli hali: x7#kQ!mz9p ← bu anlamsız görünür Arkadaşın kedi123'ü biliyorsa çözer. Bilmiyorsa çözemez.
Simetrik şifreleme gizliliği çözer ama anahtar dağıtımını çözmez. Anahtarı güvenli iletmek için başka bir mekanizma gerekiyor.
02Asimetrik şifreleme ve RSA matematiği
Kriptografinin en dahice fikirlerinden biri. İki anahtar var, matematiksel olarak birbirine bağlı. Biri şifreler, öbürü çözer.
İki anahtar, iki rol
Gerçek hayat analojisi: bir posta kutusu. Kapağında delik var, herkes mektup atabilir (açık anahtar). Ama kutuyu açma anahtarı sadece sende (özel anahtar). Herkes yazabilir, sadece sen okursun.
RSA matematiği — sıfırdan
RSA'nın dayandığı temel fikir: büyük sayıları çarpmak kolay, çarpanlarına ayırmak aşırı zordur.
Kolay yön (çarpma): 61 × 53 = 3233 ← nanosaniyede yapılır Zor yön (çarpanlarına ayırma): 3233 = ? × ? ← küçük sayıda kolay ama... Gerçek RSA'da: n = 600+ basamaklı sayı ← dünyanın tüm bilgisayarları milyarlarca yıl sürer
Örnek: asal_1 = 7, asal_2 = 11
Gerçek RSA'da bu sayılar 300+ basamaklı asal sayılardır. Anlaşılabilirlik için küçük sayılarla gidiyoruz.
# Adım 1: İki büyük asal sayı seç asal_1 = 7 asal_2 = 11 # Adım 2: Çarp çarpım = asal_1 × asal_2 = 77 # Adım 3: Euler phi hesapla euler = (asal_1 - 1) × (asal_2 - 1) = 6 × 10 = 60 # Adım 4: Açık üs seç (euler ile aralarında asal) açık_üs = 7 ← 60 ile 7 aralarında asal ✓ # Adım 5: Gizli üsü hesapla # Koşul: açık_üs × gizli_üs mod euler = 1 # yani: 7 × gizli_üs mod 60 = 1 # deneme: 7 × 43 = 301, 301 mod 60 = 1 ✓ gizli_üs = 43 ────────────────────────────────────────── AÇIK ANAHTAR = (açık_üs=7, çarpım=77) ← herkese verilir ÖZEL ANAHTAR = (gizli_üs=43, çarpım=77) ← sadece sahibinde
Şifreleme: Ayşe → Ali (mesaj = 5)
şifreli = mesaj ^ açık_üs mod çarpım şifreli = 5^7 mod 77 5^7 = 78125 78125 mod 77 = 47 Ayşe "47" gönderir. Ağı dinleyen herkes 47'yi görür — sorun değil, çözemez.
Çözme: Ali (mesaj = ?)
mesaj = şifreli ^ gizli_üs mod çarpım mesaj = 47^43 mod 77 # Büyük sayıları adım adım mod alarak hesaplıyoruz 47^1 mod 77 = 47 47^2 mod 77 = 2209 mod 77 = 53 47^4 mod 77 = 53^2 mod 77 = 37 47^8 mod 77 = 37^2 mod 77 = 60 47^16 mod 77 = 60^2 mod 77 = 58 47^32 mod 77 = 58^2 mod 77 = 53 # 43 = 32 + 8 + 2 + 1 47^43 = 47^32 × 47^8 × 47^2 × 47^1 = 53 × 60 × 53 × 47 (her adımda mod 77) 53 × 60 mod 77 = 23 23 × 53 mod 77 = 64 64 × 47 mod 77 = 5 mesaj = 5 ✓ orijinal mesaj geri geldi
Neden sadece özel anahtar çözebilir?
Saldırgan biliyor: açık_üs = 7 (açık anahtar, herkes görür) çarpım = 77 (açık anahtar, herkes görür) şifreli = 47 (ağı dinleyerek gördü) Çözmek için gizli_üs lazım. gizli_üs için → euler lazım euler için → asal_1 ve asal_2 lazım onlar için → çarpım'ı çarpanlarına ayırmak lazım çarpım = 77 → küçük sayı, 7×11 bulunur → kırılır çarpım = 617 basamaklı gerçek RSA sayısı → milyarlarca yıl
açık_üs, "açık anahtarın" parçasıdır — yani herkes bilir. "Şifreleme üssü" adı "gizli bir şey" gibi hissettirse de değildir. Açık anahtar = (açık_üs + çarpım). Gizli anahtar = (gizli_üs + çarpım). gizli_üs hesaplamak için euler lazım; o da ancak çarpanları (asal_1, asal_2) bilinirse hesaplanır.
03Dijital imza
Asimetrik şifrelemenin ters yönde kullanımı. Şifrelemede açık anahtarla şifreler, özel ile çözersin. İmzada ise özel anahtarla imzalar, açık anahtarla doğrularsın.
Şifreleme: açık anahtarla şifrele → özel anahtarla çöz
(herkes gönderebilsin, (sadece ben okuyayım)
sadece ben okuyayım)
İmza: özel anahtarla imzala → açık anahtarla doğrula
(sadece ben imzalayayım) (herkes doğrulayabilsin)
Ali bir mesajı imzalıyor (mesaj = 42)
imza = mesaj ^ gizli_üs mod çarpım imza = 42^43 mod 77 42^1 mod 77 = 42 42^2 mod 77 = 70 42^4 mod 77 = 49 42^8 mod 77 = 14 42^16 mod 77 = 42 42^32 mod 77 = 70 43 = 32 + 8 + 2 + 1 42^43 = 70 × 14 × 70 × 42 (her adımda mod 77) 70 × 14 mod 77 = 56 56 × 70 mod 77 = 70 70 × 42 mod 77 = 14 imza = 14 Ali şunu yayınlar: ┌──────────────────────────┐ │ mesaj: 42 │ │ imza: 14 │ └──────────────────────────┘ İkisi de açık gider. Herkes görür. Sorun değil.
Ayşe doğruluyor (açık anahtarla)
doğrulama = imza ^ açık_üs mod çarpım doğrulama = 14^7 mod 77 14^1 mod 77 = 14 14^2 mod 77 = 42 14^4 mod 77 = 70 7 = 4 + 2 + 1 14^7 = 70 × 42 × 14 (mod 77) 70 × 42 mod 77 = 14 14 × 14 mod 77 = 42 doğrulama = 42 mesaj = 42 EŞLEŞİYOR ✓ → Bu mesaj gerçekten Ali'den gelmiş
Saldırı senaryoları
Saldırgan Ali gibi görünerek mesaj=99 göndermek istiyor. Rastgele imza uyduruyor: 25 Ayşe doğrular: 25^7 mod 77 = 53 Mesaj: 99 53 ≠ 99 → SAHTE, reddedilir Saldırgan doğru imzayı üretmek için gizli_üs lazım. Gizli_üs sadece Ali'de. → imzalayamaz.
Ali gönderdi: mesaj=42, imza=14
Saldırgan değiştirdi: mesaj=99, imza=14 (imzayı değiştiremedi)
Ayşe doğrular: 14^7 mod 77 = 42
Gelen mesaj: 99
42 ≠ 99 → DEĞİŞTİRİLMİŞ, reddedilir
İmza orijinal mesaja matematiksel olarak bağlı.
Tek bit değişse imza tutmaz.
Pratikte hash eklenir
Gerçek dünyada mesaj megabyte'larca olabilir. Büyük veriyi doğrudan üs alma işlemine sokmak yavaş olur. Çözüm: önce mesajın hash'i alınır, sonra hash imzalanır.
Ali: mesaj_özeti = SHA-256(mesaj) ← sabit boyut, hızlı imza = mesaj_özeti ^ gizli_üs mod çarpım Ayşe: doğrulama = imza ^ açık_üs mod çarpım ← mesaj_özeti çıkar hesap = SHA-256(mesaj) ← kendi hesapladığı doğrulama == hesap → ✓
04Hash fonksiyonu
Herhangi bir veriyi sabit uzunlukta bir "parmak izi"ne dönüştürür. Tek yönlüdür — hash'ten orijinal veriye dönemezsin.
"Merhaba" → SHA-256 → 2cf24dba5fb0a30e26e83b2ac5b9e29e... "Merbaba" → SHA-256 → 9f14025af0065b27c4e5b82f... Tek harf fark — hash tamamen değişti. Bu özelliğe çığ etkisi (avalanche effect) denir.
TLS'de hash şu amaçlarla kullanılır: dijital imzada mesajın özetini almak, handshake bütünlüğünü doğrulamak (Finished mesajı), ve sertifika içeriğinin değişmediğini kanıtlamak.
05Sertifika nedir
Asimetrik şifrelemeyi biliyorsun. Ama bir sorun var: garanti.com.tr'ye bağlanıyorsun, site sana bir açık anahtar gönderiyor. Bu anahtarın gerçekten Garanti Bankası'na ait olduğunu nereden bileceksin? Sertifika bu soruyu çözer.
Sertifika şunu diyen bir belgedir: "Bu açık anahtar, şu kişiye/kuruluşa aittir. Bunu ben (güvenilir bir otorite) doğruladım ve imzaladım."
Gerçek hayat analojisi: devletin verdiği kimlik kartı. Kart üzerinde adın, fotoğrafın ve devletin mührü var. Birisi kimliğini sorduğunda kartı gösteriyorsun. Karşıdaki kişi devletin mührüne güveniyorsa, senin kim olduğuna da güvenir.
Sertifikanın iç yapısı
Sertifika dosyası ├── 1. tbsCertificate ← "imzalanacak kısım" │ ├── Versiyon: v3 │ ├── Seri numarası │ ├── İmza algoritması │ ├── Issuer: "DigiCert Intermediate CA" ← kim imzaladı │ ├── Geçerlilik: 2025-01-01 → 2026-01-01 │ ├── Subject: "banka.com" ← kime ait │ ├── Açık anahtar: (açık_üs, çarpım) ← açık anahtar │ └── Extensions │ ├── SAN: banka.com, www.banka.com ← geçerli domainler │ ├── Key Usage │ └── OCSP URL │ ├── 2. signatureAlgorithm: SHA-256 with RSA │ └── 3. signatureValue ← CA'nın gizli anahtarıyla imzalanmış
Neden hiçbir alan değiştirilemez?
CA şunu yapar: tbsCertificate içindeki her şeyi hash'e sokar: (Subject, SAN, açık anahtar, tarihler, seri no — HEPSİ) mesaj_özeti = SHA-256(tbsCertificate) imza = mesaj_özeti ^ CA_gizli_üs mod CA_çarpım → imza, sertifikaya eklenir
# Domain değiştirme "banka.com" → "sahte-banka.com" hash(değiştirilmiş tbsCertificate) ≠ orijinal hash → imza tutmaz → reddedilir # Açık anahtarı değiştirme (kendi anahtarını koyma) hash değişir → imza tutmaz → reddedilir # Tarih uzatma hash değişir → imza tutmaz → reddedilir # Yeni imza üretme CA'nın gizli anahtarı lazım → HSM'de, internetten kopuk → imkansız
06Certificate Authority ve güven zinciri
CA (Certificate Authority), sertifika imzalayan güvenilir üçüncü taraftır. Noter gibi düşün — onun mührüne herkes güvenir.
CA hiyerarşisi
Root CA (Kök Sertifika Otoritesi) └── Intermediate CA (Ara CA) └── Intermediate CA (Ara CA) └── banka.com sertifikası (leaf / son kullanıcı)
Güven zinciri doğrulaması
Tarayıcı banka.com'a bağlanıyor. Site şu zinciri gönderiyor: 1. banka.com sertifikası (leaf) → İmzalayan: DigiCert Intermediate CA 2. DigiCert Intermediate CA sertifikası → İmzalayan: DigiCert Root CA 3. DigiCert Root CA (root — genellikle gönderilmez, tarayıcıda zaten var) Tarayıcı doğrulama yapar (aşağıdan yukarı): Root CA → tarayıcının güvenilir listesinde var mı? ✓ Root CA'nın açık anahtarıyla Intermediate imzası doğrula: ✓ Intermediate'in açık anahtarıyla banka.com imzası doğrula: ✓ Hepsi geçerliyse → kilit simgesi görünür
Eğer ara sertifika eksikse, imza tutmuyorsa, veya root CA tarayıcının listesinde yoksa — tüm doğrulama başarısız olur. Tarayıcı "Bağlantınız gizli değil" hatasını gösterir.
Sertifika iptali
07TLS handshake — paket paket
İki bilgisayar güvenli konuşmaya başlamadan önce bir "el sıkışma" yaparlar. Her paketin ne zaman geldiğini, neyin gizli neyin açık olduğunu sıfırdan izliyoruz.
TLS 1.2 RSA key exchange üzerinden gidiyoruz — adımlar en görünür şekilde orada. Başlangıç durumu: tarayıcı https://banka.com adresine girmek istiyor. Henüz hiçbir şifreleme yok.
Paket 1 → İstemciden Sunucuya: ClientHello
İstemci ilk paketi gönderir: - Desteklenen TLS versiyonları: 1.2, 1.1, 1.0 - Cipher suite listesi: AES-256-CBC, ChaCha20... - client_random: 32 byte rastgele sayı ← ŞİMDİ ÜRETİLİP GÖNDERİLİYOR - SNI: "banka.com" ← hangi siteye bağlanmak istediği client_random açık gider. Herkes görür. Sorun değil — tek başına işe yaramaz. Durum: İstemcide: client_random ✓ Sunucuda: client_random ✓ Dinleyicide: client_random ✓ ← herkes biliyor, sorun yok
Paket 2 → Sunucudan İstemciye: ServerHello
Sunucu istemcinin listesinden seçer: - Seçilen versiyon: TLS 1.2 - Seçilen cipher suite: AES-256-CBC - server_random: 32 byte rastgele sayı ← SUNUCU ŞİMDİ ÜRETİP GÖNDERİYOR server_random da açık gider. Herkes görür. Sorun değil. Durum: İstemcide: client_random ✓ server_random ✓ Sunucuda: client_random ✓ server_random ✓ Dinleyicide: client_random ✓ server_random ✓ ← herkes biliyor
Paket 3 → Sunucudan İstemciye: Certificate
Sunucu sertifika zincirini gönderir (tek pakette): 1. Leaf sertifika (banka.com'un kendi sertifikası) Subject: banka.com Açık anahtar: (açık_üs, çarpım) ← sunucunun AÇIK anahtarı Issuer: "DigiCert Intermediate CA" Geçerlilik: 2025-01-01 → 2026-01-01 CA imzası: ... 2. Intermediate CA sertifikası Subject: DigiCert Intermediate CA Issuer: DigiCert Root CA CA imzası: ... Henüz doğrulama yapılmadı. Sunucu sadece gönderdi.
Paket 4 → Sunucudan İstemciye: ServerHelloDone
"Benden bu kadar. Sıra sende." — basit bir sinyal paketi, içinde veri yoktur.
★ İstemci sertifikayı doğruluyor (iç işlem, paket yok)
Ağ üzerinde hiçbir şey geçmez. Tarayıcının kendi içinde yaptığı işlemdir.
# A — Zinciri oluştur ve root CA'yı bul banka.com → imzalayan: DigiCert Intermediate CA DigiCert Intermediate CA → imzalayan: DigiCert Root CA DigiCert Root CA → tarayıcının güvenilir listesinde var mı? ✓ # B — İmzaları doğrula (aşağıdan yukarı) Root CA'nın açık anahtarı → Intermediate sertifikanın imzasını doğrula ✓ Intermediate'in açık anahtarı → banka.com sertifikasının imzasını doğrula ✓ # C — Domain kontrolü Sertifikadaki Subject/SAN: "banka.com" Ben bağlanmak istiyorum: "banka.com" Eşleşiyor mu? ✓ # D — Tarih kontrolü Bugün: 2026-04-09 Geçerlilik: 2025-01-01 → 2026-12-31 Süre dolmamış ✓ # E — İptal kontrolü (OCSP) CA'ya sor: "Bu sertifika iptal edilmiş mi?" Yanıt: "Hayır, geçerli" ✓ Tümü geçtiyse devam. Biri başarısızsa → hata sayfası
Paket 5 → İstemciden Sunucuya: ClientKeyExchange
İstemci 48 byte'lık rastgele pre_master_secret üretir. Bunu sunucunun sertifikasındaki açık anahtarla şifreler. pre_master_secret (düz): a7 3b f2 19 ... (48 byte, gizli) ↓ sunucunun açık anahtarıyla şifrelenir ↓ şifreli hali: 9c 2d e8 41 ... (şifreli, 256 byte) ↓ bu şifreli veri gönderilir Durum: İstemcide: client_random ✓ server_random ✓ pre_master_secret ✓ Sunucuda: client_random ✓ server_random ✓ pre_master_secret ? Dinleyicide: client_random ✓ server_random ✓ pre_master_secret ✗ (dinleyici şifreli halini gördü ama çözemez — sunucunun gizli anahtarı yok onda)
Sunucu pre-master secret'ı çözüyor (iç işlem)
Sunucu kendi gizli anahtarıyla çözer → pre_master_secret elde eder. Durum: İstemcide: pre_master_secret ✓ Sunucuda: pre_master_secret ✓ ← artık biliyor Dinleyicide: pre_master_secret ✗ ← hâlâ bilmiyor Her iki taraf bağımsız olarak oturum anahtarlarını türetir: master_secret = PRF(pre_master_secret, "master secret", client_random + server_random) master_secret'tan 6 anahtar türetilir: client_write_key ← istemci→sunucu trafiğini şifreler server_write_key ← sunucu→istemci trafiğini şifreler client_MAC_key ← bütünlük kontrolü server_MAC_key client_IV server_IV Kimse bu anahtarları ağ üzerinden göndermedi. Her iki taraf aynı girdilerden aynı sonucu hesapladı.
Paket 6 + 7 → Finished
İstemci → Sunucu: ChangeCipherSpec + Finished "Bundan sonra şifreli konuşuyorum" Finished içinde: tüm handshake'in hash'i, oturum anahtarıyla şifreli Sunucu → İstemci: ChangeCipherSpec + Finished Aynı şeyi yapar. Her iki taraf Finished'ı doğrular: Kendi hesapladığı hash == gelen hash? → ✓ Handshake sırasında hiçbir şey değiştirilmemiş. ═════ ARTIK HER ŞEY ŞİFRELİ ══════════════════════════════ Veri simetrik şifrelemeyle, yüksek hızda şifrelenir. Araya giren biri sadece anlamsız veri görür: x7#kQ!mz...
08Pre-master secret ve oturum anahtarı
Neden doğrudan oturum anahtarı göndermiyoruz? Neden üç bileşen? Neden TLS 1.3 bunu tamamen değiştirdi? Bunlar doğru sorular.
Neden üç bileşen?
Üç bileşen: client_random ← her bağlantıda farklı, istemci üretir server_random ← her bağlantıda farklı, sunucu üretir pre_master_secret ← her bağlantıda farklı, istemci üretir Her bağlantıda farklı random değerleri olduğu için: pre_master_secret aynı olsa bile → farklı session key üretilir. # Replay attack senaryosu Saldırgan geçmiş trafiği kaydetti. Eğer tek bileşen kullansaydık: pre_master_secret ele geçirilirse → geçmiş TÜM trafik çözülür. Üç bileşenle: Bir bağlantının pre_master_secret'ı ele geçirilse bile diğer bağlantılarda client_random ve server_random farklı → diğer bağlantıların anahtarları farklı → koruma
TLS 1.3 ve Diffie-Hellman
TLS 1.3'te RSA key exchange tamamen kaldırıldı. Bunun yerine Diffie-Hellman (ECDHE) zorunlu kılındı. Sebebi: forward secrecy (ileri gizlilik).
RSA key exchange (TLS 1.2): Saldırgan trafiği 3 yıl kaydeder. 3 yıl sonra sunucunun gizli anahtarını çalar. → Geçmiş 3 yılın TÜM trafiğini çözer. 😱 Diffie-Hellman (TLS 1.3): Her bağlantıda geçici (ephemeral) anahtar çifti üretilir. Bağlantı bitince geçici anahtarlar silinir. 3 yıl sonra sunucu anahtarı çalınsa da: → Geçici anahtarlar çoktan silinmiş. → Geçmiş trafik çözülemez. ✓
İstemci: geçici DH anahtar çifti üretir
→ açık kısmını ClientHello'da gönderir
Sunucu: geçici DH anahtar çifti üretir
→ açık kısmını ServerHello'da gönderir
Her iki taraf bağımsız olarak hesaplar:
kendi gizli DH anahtarı × karşının açık DH anahtarı
→ aynı shared_secret çıkar
Ağı dinleyen biri her iki açık değeri de görür.
Ama shared_secret'ı hesaplayamaz.
Bu matematiksel olarak "ayrık logaritma problemi"ne dayanır.
09mTLS — karşılıklı kimlik doğrulama
Normal TLS'te sadece sunucu kendini istemciye kanıtlar. istemci anonim kalır. mTLS'te her iki taraf da sertifika gösterir.
Normal TLS'in sınırı
Normal TLS:
İstemci → Sunucu: "Sen kimsin?"
Sunucu → İstemci: "Al sertifikam, doğrula." ✓
Sunucu → İstemci: "Sen kimsin?" ← SORULMUYOR
Kimlik doğrulama uygulama katmanında yapılır (login formu, token vb.)
Çoğu durumda yeterli.
mTLS:
İstemci → Sunucu: "Sen kimsin?"
Sunucu → İstemci: "Al sertifikam." ✓
Sunucu → İstemci: "Sen de kimsin? Sertifikanı göster."
İstemci → Sunucu: "Al benim sertifikam." ✓
Her iki taraf da birbirini doğruladı.
mTLS handshake'e eklenen üç adım
İstemci Sunucu | | |──── ClientHello ───────────────────────→| |←─── ServerHello ────────────────────────| |←─── Sunucu Sertifikası ─────────────────| |←─── ★ CertificateRequest ──────────────| ← EK ADIM 1 | "Bana da sertifika göster" | | | |──── ★ İstemci Sertifikası ────────────→| ← EK ADIM 2 |──── Key Exchange ──────────────────────→| |──── ★ CertificateVerify ──────────────→| ← EK ADIM 3 | İstemci özel anahtarıyla imzalar | | "Bu sertifika gerçekten bende" | | | |──── Finished ──────────────────────────→| |←─── Finished ───────────────────────────| | | |═════ KARŞILIKLI DOĞRULANMIŞ KANAL ══════|
Nerede kullanılır?
Karşılaştırma
| Özellik | TLS | mTLS |
|---|---|---|
| Sunucu kimliği | Doğrulanır ✓ | Doğrulanır ✓ |
| İstemci kimliği | Doğrulanmaz | Doğrulanır ✓ |
| Sertifika gereken | Sadece sunucu | Her iki taraf |
| Kullanım alanı | Web siteleri, genel internet | Servisler arası, kurumsal sistemler |
| Karmaşıklık | Düşük | Yüksek (her istemciye sertifika lazım) |
10CSR ve ACME Challenge
CA'ya "bana sertifika ver" demenin resmi yolu: Certificate Signing Request. CA sadece CSR almakla yetinmez — domain'in gerçekten senin olduğunu da kanıtlamanı ister.
CSR nedir ve içinde ne var?
CSR dosyası ├── 1. Bilgiler (imzalanacak kısım) │ ├── Domain adı: banka.com │ ├── Kuruluş: Banka A.Ş. │ ├── Şehir: İstanbul │ ├── Ülke: TR │ └── Açık anahtar: (açık_üs, çarpım) ← AÇIK ANAHTAR │ ← ÖZEL ANAHTAR YOK │ ├── 2. İmza algoritması: SHA-256 with RSA │ └── 3. İmza: senin kendi gizli anahtarınla imzalanmış
Neden CSR'a imza koyuyoruz?
İmzasız CSR: Ali'nin açık anahtarı bir şekilde internette yayınlanmış. Saldırgan alıyor, sahte CSR oluşturuyor: domain: banka.com açık anahtar: Ali'ninki ← Ali'nin anahtarını koydu CA'ya gönderiyor. Domain doğrulamasını geçerse → sertifika verilir → kaos. İmzalı CSR: Saldırgan Ali'nin açık anahtarıyla CSR oluşturuyor. İmzayı üretmesi lazım → Ali'nin gizli anahtarı gerekli → yok. CA imzayı doğrular → tutmaz → reddedilir.
Tam CSR süreci
# 1. Kendi bilgisayarında anahtar çifti üret $ openssl genrsa -out gizli_anahtar.key 2048 # 2. CSR oluştur (gizli anahtar dışarı çıkmaz, sadece imzalar) $ openssl req -new -key gizli_anahtar.key -out basvuru.csr # CSR'da: açık anahtar + bilgiler + senin imzan # Özel anahtar: hiç dışarı çıkmadı # 3. CSR'ı CA'ya gönder (Let's Encrypt, DigiCert vb.) # 4. CA domain'i doğrular (ACME Challenge) # 5. CA sertifikayı imzalar, sana gönderir # → CSR'dan: açık anahtar, domain # → CA'nın eklediği: tarihler, seri no # → CA'nın kendi gizli anahtarıyla imzası # 6. Sertifikayı + gizli anahtarı web sunucuna yükle
ACME Challenge — domain doğrulaması
CA'nın en kritik adımı. İmza geçerli olsa bile saldırgan kendi anahtarıyla CSR oluşturabilir. Domain'in gerçekten senin olduğu kanıtlanmalı.
SEN CA (Let's Encrypt)
─── ──────────────────
"banka.com için sertifika istiyorum" ────→
←──── "Kanıtla. Şu dosyayı koy:
http://banka.com/.well-known/
acme-challenge/abc123xyz
İçeriği: abc123xyz.HESAPANAHTARIN"
Sunucuna gidip dosyayı koyuyorsun. ────→ "Hazır, kontrol et."
CA o URL'ye erişir.
İçerik doğru mu? ✓
←──── "Domain senin. Al sertifikan."
Mantık: o sunucuya dosya koyabiliyorsan → sunucuyu kontrol ediyorsun
→ domain senin. Saldırgan banka.com sunucusuna dosya koyamaz → geçemez.
CA: "Şu DNS kaydını ekle:
_acme-challenge.banka.com TXT "x7k9m2pQ4rT...""
Sen DNS panelinden kaydı ekliyorsun.
CA sorguluyor:
_acme-challenge.banka.com TXT = "x7k9m2pQ4rT..." ✓
Kullanım: DNS Challenge ile *.banka.com (wildcard) sertifikası alınır.
HTTP Challenge ile wildcard alınamaz.
İmza tek başına yetmez: "bu açık anahtarın gizli anahtarı bende" kanıtlar ama banka.com'un sahibi olduğunu kanıtlamaz. Domain doğrulaması tek başına yetmez: domain senin ama hangi açık anahtarla sertifika verilecek belli değil. İkisi birlikte: sahip doğrulandı + anahtar doğrulandı → sertifika güvenle verilebilir.
11Özet tablosu
Tüm kavramlar, tek tabloda.
| Kavram | Ne iş yapar | Analoji |
|---|---|---|
| Simetrik şifreleme | Aynı anahtarla şifrele/çöz | Evin kapı anahtarı |
| Asimetrik şifreleme | Açık anahtarla şifrele, gizliyle çöz | Posta kutusu |
| Dijital imza | Gizli anahtarla imzala, açıkla doğrula | Islak imza + noter |
| Hash | Verinin sabit boyutlu parmak izi | Parmak izi |
| Sertifika | Açık anahtar + kimlik + CA imzası | Kimlik kartı |
| CA | Sertifika veren güvenilir kurum | Nüfus müdürlüğü |
| Root CA | En tepedeki otorite, tarayıcıda önceden yüklü | Devlet |
| Intermediate CA | Root adına çalışan ara otorite | Valilik |
| TLS | Güvenli kanal kurma protokolü | Zırhlı araç |
| TLS Handshake | Güvenli kanalı başlatma süreci | El sıkışma + kimlik kontrolü |
| client/server random | Her bağlantıda farklı, replay saldırısını önler | Oturum numarası |
| pre-master secret | Oturum anahtarının ham maddesi | Ortaklaşa atılan zar |
| Session key | Asıl veriyi şifreleyen geçici anahtar | Tek kullanımlık şifre |
| Forward secrecy | Gizli anahtar çalınsa geçmiş trafik güvende | Yakılan günlük |
| mTLS | Her iki taraf da sertifika gösterir | Karşılıklı kimlik kontrolü |
| CSR | CA'ya sertifika başvurusu | Nüfusa başvuru formu |
| ACME Challenge | Domain'in sahibini otomatik doğrulama | Posta kutusuna mektup bırakma |
| OCSP | Sertifikanın iptal edilip edilmediğini sorgulama | Kaçak araç sorgulaması |
Tek cümlede TLS nedir
TLS, asimetrik şifrelemeyi sadece başta simetrik anahtarı güvenle iletmek için, sonra simetrik şifrelemeyi hızlı veri transferi için kullanan; sertifikalar ve CA hiyerarşisiyle kimlik doğrulamayı çözen; hash ve imzalarla bütünlüğü garantileyen hibrit bir protokoldür.
Yaygın tarayıcı hataları ve anlamları
- NET::ERR_CERT_AUTHORITY_INVALID — CA tarayıcının güvenilir listesinde değil (self-signed sertifika veya bilinmeyen CA)
- Sertifikanın süresi dolmuş — geçerlilik tarihi geçmiş, yenilenmeli
- Sertifika adı eşleşmiyor — sertifika example.com için ama sen www.example.com'a girdin
- Karışık içerik (Mixed content) — sayfa HTTPS ama bazı kaynaklar HTTP üzerinden yükleniyor