Parolalar veri tabanlarında güvenli olarak nasıl saklanır?

Bu flood’da uygulamalarda kimlik denetimi yapılmasını sağlayan parolaların veri tabanında güvenli olarak nasıl tutulabileceğini anlatacağım.

Sistemimizdeki güvenlik açıkları (SQL Injection, vb) sebebiyle veri tabanımıza üçüncü kişiler erişim sağlayabilir ve kullanıcıların parolaları ile birlikte diğer bilgileri çalınabilir. Bununla birlikte sisteme erişim hakkı olan kötü niyetli çalışanlar (iç tehditler) da güvenli bir biçimde korunmadığında kullanıcı parolalarını görebilirler. Kullanıcılar aynı parolaları başka uygulamalarda da kullandıkları için kullanıcıların diğer hesaplarının da ele geçirilme tehlikesi ortaya çıkar. Dolayısıyla parola güvenliğini sağlamak elzemdir.

Şimdi veri tabanındaki parola güvenliğini sağlayabileceğimiz yöntemleri en zayıf olandan en güçlü olana doğru ele alalım.

Akla ilk gelen yöntem parolalarının önceden belirlenmiş bir şifre kullanılarak AES veya DES3 gibi bir simetrik şifreleme algoritmasıyla şifrelenmesidir. Veri tabanı ele geçse dahi şifre bilinmeden parolaları ele geçirmek mümkün olmayacaktır ancak şifrenin güvenli olarak saklanmasının yönetilmesi ve şifrenin kendisinin de veri tabanı ile birlikte ele geçme riski nedeniyle bu yöntem pek güvenli değildir.

İkinci yöntem önceki flood’da anlatıldığı gibi parolanın hash’ini alıp hash’i saklamak olabilir, böylece parolanın kendisi tutulmamış olur. Bu yöntem kulağa hoş gelse de Rainbow Attack adı verilen önceden hesaplanmış hash veri tabanları ile yapılan ataklara karşı korumasızdır. Rainbow Tablelar 10, 11, 12, vb uzunluktaki parola kombinasyonları için MD5, SHA-1, vb hash'leri içerir ve hash'ten dönüşüm sağlarlar.

2012 yılında, LinkedIn ağına giren saldırganlar bu yöntem kullanılarak sadece hash’i saklanan 167M parolanın açığa çıkmasına sebep olmuştur.

Aşağıda online Rainbow Table hizmeti veren bir sistemde karmaşık sayılabilecek d71lWz9zjS parolası hash'inden geriye dönüştürülmüştür.

Üçüncü yöntem parolayı bir kere hash’lemek yerine seçilen bir sayı (100, 200, vb) kadar iteratif olarak aşağıdaki gibi hash’lemektir. Bu yöntemi kırmak üzere değişik sayıda hash için üretilmiş Rainbow Tablelar da bulunmaktadır. Dolayısıyla bu yöntem de güvenli sayılmaz.

Dördüncü yöntem, son iki yöntemdeki Rainbow Attacklara karşı dirençli olmak için üretilen tuzlamadır (salting).

Rainbow Attackların başarılı olma sebebi doğaları gereği (hatırlanmak için) kısa tutulan parolalardır. Dördüncü yöntemde, her bir parola için özel rastsal bir salt (tuz) üretilir ve veri tabanında saklanır. Parola ve tuz birleştirilerek hash'i alınıp veri tabanında saklanır. Parola + tuz fazla uzun olduğu için bu girdi için Rainbow Table üretmek uygulanabilir (feasible) değildir ve etkisizdir. Bununla birlikte bu yöntem, saniyede milyarca hash üretebilen modern GPU'lar ile yapılan Brute Force Attacklara karşı dayanıksızdır.

Yukarıda anlatılan dördüncü yöntem aşağıda görselleştirilmiştir.

2017 itibariyle güvenli sayılan ilk yöntem Password Based Key Derivation Functions (PBKDF2)dir. Bu yöntemde aşağıdaki gibi parola ve tuz birleştirilerek hash'lenir, bu işlemden elde edilen sonuç bir sonraki iterasyonda tuz olarak kullanılarak, işlem N kere tekrarlanır. Bu sayede hem Brute Force hem de Rainbow Attacka karşı direnç kazanılmış olur. Modern framework'lerde N, 1000 olarak belirlenmiştir.

Bu yöntemde N’i doğru belirlemek önemlidir. Küçük N ile sistem güvenliği azalacak, büyük N ile ise fazla işlemci gücü gerekecektir. Fazla işlemci gücü harcanması, hatalı parolalarla giriş işlemi denenerek yapılan bir DoS (Denial of Service) atağına sistemi açık hale gelecektir.

Güvenli sayılan ikinci yöntem bcrypt parola hash algoritmasıdır. bcrypt genel amaçlı hash algoritmalarına göre milyarlarca kez yavaş çalıştığı için Brute Force Attacklara, kullandığı salt ile de Rainbow Attacklara karşı dayanıklı kabul edilmektedir.

bcrypt ve PBKDF2 fonksiyonlarının zayıf ve güçlü yönlerini ilerleyen flood'larda detaylı olarak ele alacağız.