Bir Depolama Biçimini Kurtarılabilir Yapan Nedir
Kurtarılabilirliklerine göre sıralanmış dört depolama biçimi:
| Biçim | Kurtarılabilir mi? | Örnek | Kurtarma Yöntemi |
|---|---|---|---|
| Düz Metin | Evet | password: hunter2 | Dosyayı oku |
| Base64 | Evet | cGFzc3dvcmQ= | base64 --decode |
| Tersine çevrilebilir şifre (AES) | Evet | ENC[AES256:...] | Anahtarla çöz |
| Tek yönlü hash (bcrypt) | Hayır | $2b$12$... | Tersine çevrilemez; brute-force gerekir |
Düz metin, base64 ve tersine çevrilebilir şifre: hepsi kurtarılabilir. Tek bir kimlik bilgisi veritabanı dökümü, saldırgana tüm kullanıcıların parolalarını aynı anda düz metin olarak verir. Tek ihlal; tam maruziyet.
Mailman 2.x Örneği
Mailman 2.x (GNU posta listesi yöneticisi): abone parolalarını düz metin olarak saklıyordu. Aylık parola hatırlatma e-postası: tüm abonelere parolalarını düz metin olarak gönderiyordu. İki ayrı kusur, ikisi de MOAD-0006:
1. Depolama: liste veritabanında düz metin. Sunucu ihlali tüm abone parolalarını açığa çıkarır.
2. Yayın: aylık e-posta, düz metin parolayı SMTP üzerinden abonenin e-posta sunucusuna gönderir. E-posta birden fazla SMTP atlaması boyunca düz metin olarak dolaşır.
Mailman ekibi her iki davranışı da tasarladı. Kurtarma özelliğiydi: aboneler unutulan parolaları geri alabiliyordu. Glass Safe adı buradan gelir: kasa kimlik bilgilerini görünür biçimde tutar. Kasaya ulaşan herkes tüm içerikleri aynı anda okuyabilir.
Zaten Çalınmış İlkesi
Kurtarılabilir biçimde saklanan bir kimlik bilgisi, zaten çalınmış bir kimlik bilgisidir. Saldırgan henüz gelmemiştir. İhlal henüz gerçekleşmemiştir. Ancak mimari garanti eder: bir ihlal meydana geldiğinde tüm kimlik bilgileri aynı anda düşer. Hiçbir ihlal yalıtılmış şekilde gerçekleşmez; kurtarılabilir depolamadaki her kimlik bilgisi aynı işlemde saldırgana aktarılır.
MOAD-0006 vs MOAD-0004
MOAD-0004 (Günlüğe Yazılan Gizli): kimlik bilgileri yanlışlıkla günlüklere yazılır. Günlük yazımı amaçlanmamıştı; hata ayıklama için başlık günlüğünü etkinleştirmenin yan etkisidir.
MOAD-0006 (Glass Safe): kimlik bilgileri tasarlanarak kurtarılabilir biçimde saklanır. Kurtarma amaçtı. Parola hatırlatma özelliği parolayı saklamayı gerektiriyordu. Parolayı gösterme özelliği de onu saklamayı gerektiriyordu. Kurtarmaya yönelik mimari taahhüt, kusuru yarattı.
Tek satırlık ayrım: MOAD-0004 kimlik bilgilerini kazara günlüklere koyar; MOAD-0006 kimlik bilgilerini kasıtlı olarak kurtarılabilir biçimde saklar. Düzeltmeler farklı katmanlarda çalışır.
Yapısal vs Kazara
MOAD-0006 ile MOAD-0004 arasındaki mimari ayrım, düzeltme stratejisini belirler. Kazara yapılan log yazımı: serileştirme katmanını düzeltin. Kurtarma için tasarlanmış depolama: kurtarma gerektiren özelliği yeniden tasarlayın.
Neden bcrypt Çalışır
Tek yönlü özet fonksiyonu bir parola alır ve sabit uzunlukta bir özet üretir. Özet verildiğinde orijinal parola geri kazanılamaz. “Kurtarmak zor” değil: tersine çevirmek imkânsızdır. Fonksiyon yalnızca tek yönde çalışır.
Kimlik bilgisi depolama için gerekli üç özellik:
1. Tek yönlü (ön görüntü direnci). hash(password) verildiğinde, hiçbir algoritma password'ü kaba kuvvetten daha hızlı geri getiremez. bcrypt, scrypt ve argon2 bu özelliği karşılar.
2. Tuz (Salt). Paroladan önce eklenen rastgele bir değer. Aynı parola, farklı tuz, farklı hash. Amaç: rainbow tablolarını (önceden hesaplanmış hash sözlükleri) etkisiz hale getirmek. Tuz olmadan: bir saldırgan hash('password123') değerini bir kez hesaplar ve 1 milyon kullanıcının tümünü aynı anda kontrol eder. Tuz ile: aynı parola için bile her kullanıcının benzersiz bir hash'i olur.
3. Tasarım gereği yavaş. bcrypt bir iş faktörü kabul eder. Daha yüksek iş faktörü: daha fazla yineleme, her hash denemesi için daha fazla işlem süresi. Giriş: bir kez hash'lemek için 300ms. Kabul edilebilir. Kaba kuvvet: her deneme için 300ms. 1 milyar denemede: parola başına 9,5 yıl. Bir saldırgan için kabul edilemez. Yavaşlık: bir kusur değil, bir özelliktir.
import bcrypt
# Depola: tuz ile tek yönlü hash
def store_password(plaintext: str) -> bytes:
return bcrypt.hashpw(plaintext.encode(), bcrypt.gensalt(rounds=12))
# Doğrula: aday metni hash'le ve özetleri karşılaştır
def verify_password(plaintext: str, stored_hash: bytes) -> bool:
return bcrypt.checkpw(plaintext.encode(), stored_hash)
# ASLA saklanmaz: düz metin parola
# ASLA kurtarılamaz: hash'ten düz metin
# Parola sıfırlama, parola hatırlatma değil
Ödünleşme
Tek yönlü hash'leme, parola kurtarmayı imkânsız kılar. Parolasını unutan bir kullanıcı parolasını geri alamaz. Parola hatırlatma e-postası olamaz. Kullanıcı deneyimi değişir: 'parolanızı mı unuttunuz? sıfırlayın.' Bu bir gerileme değildir: bir güvenlik sınırıdır. Parolayı kurtaramayan sistem, parolayı sızdıramaz.
bcrypt hash'lerini açığa çıkaran bir veritabanı ihlali: tüm hash'ler görünür, hiçbir parola görünmez. Bir saldırgan her hash'i tek tek kaba kuvvetle kırmak zorundadır; her deneme 300 ms sürer ve kullanıcı başına tuz, önceden hesaplanmış tabloları etkisiz kılar. Düz metin parolaları açığa çıkaran bir ihlal: anında tam maruziyet.
Güçlü Şifreleme Yeterli Değildir
Bir güvenlik denetimi, bir kimlik doğrulama depolama sistemi tespit eder. Parolalar sunucu tarafı bir anahtarla AES-256-CBC şifrelemesi kullanılarak saklanmaktadır. Denetim raporu bunu Glass Safe kusuru olarak işaretler.
Mühendislik ekibi yanıt veriyor: 'AES-256 mevcut en güçlü simetrik şifreleme algoritmasıdır. Anahtar bir donanım güvenlik modülünde (HSM) saklanır. Hiçbir saldırgan bu parolaları çözemez.'