Joe Programmer'ın son kullanıcı şifrelerini bir web uygulaması için bir veritabanında güvenli bir şekilde saklamakla görevlendirildiğini varsayalım; veya bir yazılımda oturum açmak için şifreleri diskte saklamak. Büyük olasılıkla:
$passwordEdinin.
$nonceOluşturun.
$hash = SHA256($nonce$password)oluşturun ve
$nonceİle birlikte
$hashVeritabanında saklayın.
Birinci soru:
Aşağıdakiler neden yukarıdakilerden önemli ölçüde daha iyi değil?
$long_stringOluşturun. Bunu uygulama kodunda sabit olarak saklayın.
$long_stringF.x olabilir. 2 kilobayt rastgele karakter olabilir.
$passwordEdinin.
$mac = HMAC-SHA256($long_string)[$password]oluşturun (yani son kullanıcı şifresini anahtar olarak kullanarak bir MAC oluşturun) ve bu
$macDosyasını veritabanında saklayın.
HMAC'nin aşağıdaki faydaları olduğunu düşünürdüm?
$macDepolanan veritabanı, ve 2) orijinal
$long_string'un saklandığı uygulama kodu. Bu, saldırganın veritabanına yalnızca erişmesi gereken bir karma işlevden daha iyi mi?
Ama yine de, kimse bir HMAC kullanmayı önermiyor gibi görünüyor, bu yüzden bir şeyi yanlış anlamam gerekir mi?
İkinci soru:
Tuz değeri eklemenin sonuçları
$nonce Ne olurdu?
$long_stringOluşturun. Bunu uygulama kodunda sabit olarak saklayın.
$passwordEdinin.
$nonceOluşturun.
$mac = HMAC-SHA256($long_string)[$nonce$password]oluşturun ve veritabanında
$nonceVe
$macDepolayın.
Tuzun amacı saldırı maliyeti paylaşımını önlemektir: bir saldırgan iki parola saldırmak istiyorsa, bir parolaya saldırmaktan iki kat daha pahalı olmalıdır.
Teklifinizle ("soru 1"), aynı şifreye sahip iki kullanıcı aynı MAC'yi kullanır. Bir saldırgan veritabanınıza okuma erişimine sahipse, şifreleri "deneyebilir" (MAC'i yeniden hesaplayarak) ve veritabanını eşleşme için arayabilir. Daha sonra parolalara saldırmanın bedeli olarak tümü şifreleri paralel olarak saldırabilir. Eğer senin
long_string, uygulama kaynak kodunda sabit kodlanmış bir sabittir, daha sonra uygulamanın yüklü tüm örnekleri bu sabiti paylaşır ve "a" olarak da bilinen büyük bir parola-MAC çifti sözlüğünü önceden hesaplamaya değer (saldırgan için) "Gökkuşağı tablosu".
Bir nonce ("soru 2") ile maliyet paylaşımından kaçınırsınız. Nonce genellikle "tuz" olarak bilinir. Sizin
long_string. Bir tuz kullanmak çok iyi bir fikirdir (iyi, değil bir tuz kullanmak en azından çok kötü bir fikirdir) ama işin sadece yarısını yapar. Ayrıca yavaş karma işlemine sahip olmalısınız. Buradaki nokta, tuzun maliyet paylaşımını önlediği, ancak tek bir parolaya saldırmayı önlemediği. Bir parola saldırmak, bir eşleşme olana kadar olası parolaların denenmesi anlamına gelir (bu "sözlük saldırısı" dır) ve ortalama bir insan kullanıcısının hayal gücü göz önüne alındığında, sözlük saldırıları işe yarar: insanlar sadece love tahmin edilmek. Çözüm, genellikle karma işlevini birkaç bin kez yineleyerek, doğal olarak yavaş olan bir karma işlemi kullanmaktır. Fikir parola doğrulamasını daha pahalı hale getirmektir: kullanıcının 1µs yerine 1ms beklemesi zor değildir (kullanıcı bunu fark etmez), ancak sözlük saldırısını 1000 kat daha pahalı hale getirir. Sizin
long_stringmayıs çok uzun olması koşuluyla bunun için kullanılabilir (2 kilobayt değil, 20 megabayt).
HMAC may şifre doğrulama sistemini güçlendirmek için farklı bir kurulumda ham karma işlevi yerine kullanılabilir. Şifreleri tuzlarla ve yinelenen karma işlevleriyle kontrol eden bir sistem göz önüne alındığında, karma işlevini K kullanarak HMAC ile değiştirebilirsiniz. Bu, K gizli tutabildiğiniz sürece çevrimdışı sözlük saldırılarını önler. Bir değeri gizli tutmak kolay değildir, ancak 128-bit K sırrını tam bir veritabanından tutmak daha kolaydır.
HMAC sizi burada çok fazla satın almıyor olsa da sanırım değiştirilebilir bir hash fonksiyonu olarak işlev görüyor (anahtarı değiştirerek değiştirilebilir). Her neyse, burada aşırıya kaçmış gibi görünüyor.
Bununla birlikte, eğer $ long_string bir saldırgan tarafından bilinirse, yukarıda önerdiğiniz ilk şema felaketle başarısız olur, bu muhtemelen kod muhtemelen gizli olarak kabul edilmez (ve yine de kodun gizliliğine güvenmek zayıf bir uygulamadır).
Önceden hesaplanmış saldırılara karşı korunmak için $ nonce gerektiğinden, ikinci şemayı kullanmalısınız.