Güvenli Şifre Saklama Yöntemleri
# Güvenli Şifre Saklama YöntemleriBir kullanıcı kaydı formu yazdın. Şifreyi veritabanına yazacaksın. Burada verdiğin karar, veritabanı sızdığı gün tek savunma hattın olacak. Düz metin şifre saklamak artık kabul edilebilir bir hata değil; ama "MD5'ledim, tamam" demek de aynı derecede riskli.
Amaç şu: veritabanı komple kopyalansa bile saldırgan şifreleri kullanamasın. Bunu sağlayan üç şey var: doğru algoritma, her kullanıcıya özel salt, ve yeterince yavaş bir hesaplama. Aşağıda bunları tek tek, uygulanabilir şekilde ele alıyoruz.
Hashing Temelleri ve Doğru Algoritma Seçimi
Şifreyi saklamıyorsun. Şifrenin parmak izini saklıyorsun. Kullanıcı giriş yaptığında yeni parmak izini alıp eskisiyle karşılaştırıyorsun. Bu yüzden geri döndürülemez olması özellik, eksiklik değil.
Hash ile Şifreleme Arasındaki Fark
Bu ikisi karıştırıldığında çok kötü kodlar çıkıyor. Kısa ayrım:
- Hash: Tek yönlüdür. Geri açılamaz. Şifreler için doğru araç.
- Encryption: İki yönlüdür. Anahtarla açılır. Kredi kartı, TC kimlik, API token gibi geri okuman gereken veriler için.
Şifreyi encryption ile saklarsan, anahtar da sızdığında bütün şifreler düz metin olur. Password hashing encryption ayrımını en basit haliyle şöyle hatırla: şifreyi hiçbir zaman geri okumana gerek yok, sadece doğrulaman lazım.
Hangi Algoritma?
Modern kullanımda üç isim öne çıkıyor:
| Algoritma | Durum | Not |
|---|---|---|
| bcrypt | Güvenli, yaygın | Her dilde olgun kütüphanesi var. 72 byte girdi sınırı unutulmamalı. |
| Argon2id | Güvenli, modern | Bellek maliyeti de ayarlanabilir. Yeni projede ilk tercih. |
| scrypt | Güvenli | Bellek yoğun. Argon2'ye alternatif. |
| MD5 / SHA-1 / SHA-256 | Şifre için kullanma | Çok hızlı. Saniyede milyarlarca deneme yapılabilir. |
SHA-256 kötü bir hash değil; dosya bütünlüğü için mükemmel. Sorun hız. Şifre saklamada yavaşlık istiyorsun.
Salt ve Pepper
Salt, her kullanıcı için üretilen rastgele bir değer. Şifreye eklenip hash'lenir. Faydası:
- Aynı şifreyi kullanan iki kullanıcı farklı hash'e sahip olur.
- Hazır rainbow table'lar işe yaramaz.
- Saldırgan her hash'i tek tek kırmak zorunda kalır.
İyi haber: bcrypt ve Argon2 salt'ı kendisi üretir ve çıktı stringinin içine gömer. Ayrı bir salt kolonu açmana gerek yok. Kendi salt'ını elle üretmeye kalkışmak genelde hata kaynağı.
Pepper ise uygulama genelinde tek olan, veritabanında durmayan gizli bir ek değer. Ortam değişkeninde veya secret manager'da tutulur. Veritabanı tek başına sızarsa ekstra bir katman sağlar. Zorunlu değil, ama ucuz bir kazanç.
Uygulamada Doğru Kurulum
Teori tamam. Şimdi kodda ve süreçte nelere dikkat edeceğine bakalım.
Maliyet Parametresini Ayarlamak
bcrypt'te "cost" ya da "rounds" denen bir değer var. Her artışta hesaplama süresi iki katına çıkar. Nasıl seçeceksin:
- Kendi sunucunda ölçüm yap. Tek hash yaklaşık 200–300 ms sürsün.
- Çok hızlıysa değeri bir artır, tekrar ölç.
- Login endpoint'inin gecikmesini kullanıcı zaten fark etmez; brute-force saldırganı fark eder.
- Bu değeri kodda sabit yazma. Konfigürasyondan oku, sunucu güçlendikçe yükselt.
Argon2 kullanıyorsan zaman maliyeti, bellek maliyeti ve paralellik olarak üç parametre var. Belleği cömert tut; asıl korumayı o sağlıyor.
Kod Tarafında Klasik Hatalar
Aşağıdakiler sık görülen ve gerçekten zarar veren hatalar:
- Kendi hash fonksiyonunu yazmak. Yapma. Dilin standart kütüphanesini veya olgun bir paketi kullan.
- Karşılaştırmayı
==ile yapmak. Kütüphanenin verify/compare fonksiyonunu kullan. Zamanlama saldırılarına karşı sabit süreli karşılaştırma yapar. - Şifreyi log'lamak. Request body'yi olduğu gibi log'a basan middleware'ler en büyük sızıntı kaynağı. Şifre alanını maskele.
- Hash'i önce SHA'lamak, sonra bcrypt'e vermek. Gerekmiyorsa karmaşıklık ekleme. (Sadece 72 byte sınırını aşan uzun passphrase desteği için bilinçli yapılır.)
- Şifreyi frontend'de hash'leyip göndermek. O zaman hash'in kendisi şifre olur. Sunucuda hash'le, arada HTTPS kullan.
- Uzunluk üst sınırını 12 karaktere çekmek. Minimum koy (8–12), maksimumu bol tut (64+). Karakter tipi zorunluluğu yerine uzunluğu teşvik et.
Migrasyon ve Bakım
Elinde MD5 dolu eski bir tablo varsa şifreleri yeniden hash'lemek için düz metne ihtiyacın var — yok. Çözüm kademeli geçiş:
- Kullanıcı tablosuna algoritma sürümünü tutan bir kolon ekle.
- Kullanıcı doğru şifreyle giriş yaptığı anda elinde düz metin var. O anda bcrypt/Argon2 ile yeniden hash'le ve kaydı güncelle.
- Bir süre sonra hâlâ eski formatta kalanları zorunlu şifre sıfırlamaya yönlendir.
- Maliyet parametresini yükselttiğinde de aynı yöntem işe yarar: girişte "rehash gerekli mi" kontrolü yap.
Ek olarak login denemelerine hız sınırı koy.