Bcrypt'in yerleşik tuzları nasıl olabilir?


617

Coda Hale makale "Güvenle bir Parola Mağaza Nasıl" yönündeki iddiaları:

bcrypt, gökkuşağı tablosu saldırılarını önlemek için yerleşik tuzlara sahiptir.

OpenBSD'nin uygulanmasında şunları söyleyen bu makaleye atıfta bulunur bcrypt:

OpenBSD, çekirdeğin cihaz zamanlamalarından topladığı rasgele verilerle tohumlanmış bir arcfour (arc4random (3)) anahtar akışından 128 bit bcrypt tuzunu üretir.

Bunun nasıl çalıştığını anlamıyorum. Benim bir tuz anlayışımda:

  • Saklanan her şifre için farklı olması gerekir, böylece her biri için ayrı bir gökkuşağı tablosu oluşturulmalıdır
  • Tekrarlanabilir olması için bir yerde saklanması gerekir: bir kullanıcı giriş yapmaya çalıştığında, şifre girişimlerini dener, ilk olarak şifrelerini sakladığımızda yaptığımız aynı tuz ve karma prosedürünü tekrarlar ve karşılaştırırız.

Bcrypt ile Devise (bir Rails giriş yöneticisi) kullandığımda, veritabanında tuz sütunu yok, bu yüzden kafam karıştı. Tuz rastgele ve hiçbir yerde saklanmazsa, hash işlemini nasıl güvenilir bir şekilde tekrarlayabiliriz?

Kısacası, bcrypt'in yerleşik tuzları nasıl olabilir ?

Yanıtlar:


789

Bu bcrypt:

Rastgele bir tuz üret. Bir "maliyet" faktörü önceden yapılandırılmıştır. Bir şifre toplayın.

Tuz ve maliyet faktörünü kullanarak paroladan bir şifreleme anahtarı elde edin. Tanınmış bir dizeyi şifrelemek için kullanın. Mağaza maliyet tuz, ve şifre metin. Bu üç elementin bilinen bir uzunluğu olduğundan, bunları birleştirmek ve tek bir alanda saklamak kolaydır, ancak daha sonra ayırabilirler.

Birisi kimlik doğrulaması yapmaya çalıştığında, depolanan maliyeti ve tuzu alın. Giriş şifresi, maliyet ve tuzdan bir anahtar elde edin. Aynı iyi bilinen dizeyi şifreleyin. Oluşturulan şifre metni saklanan şifre metniyle eşleşiyorsa, şifre bir eşleşmedir.

Bcrypt, PBKDF2 gibi algoritmalara dayanan daha geleneksel şemalara çok benzer bir şekilde çalışır. Temel fark, bilinen düz metni şifrelemek için türetilmiş bir anahtarın kullanılmasıdır; diğer şemalar (makul olarak) anahtar türetme işlevinin geri döndürülemez olduğunu varsayar ve türetilen anahtarı doğrudan saklar.


Veritabanında saklanan bir bcrypt"karma" şuna benzer:

$ 2a $ 10 $ vI8aWBnW3fID.ZQ4 / zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa

Bu aslında "$" ile ayrılmış üç alan:

  • 2abcryptkullanılan algoritma sürümünü tanımlar .
  • 10maliyet faktörü; 2 Anahtar türetme işlevinin 10 yinelemesi kullanılır (bu arada, yeterli değildir. 12 veya daha fazla bir maliyet öneriyorum.)
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTa"Far" terimi, modifiye edilmiş bir Base-64 içinde birleştirilen ve kodlanan tuz ve şifreleme metnidir. İlk 22 karakter, tuz için 16 bayt değerinde bir kodu çözer. Kalan karakterler, kimlik doğrulama için karşılaştırılacak şifre metnidir.

Bu örnek, Coda Hale'in yakut uygulamasının belgelerinden alınmıştır .


7
10'lu maliyet faktörünün neden yeterli olmayacağına dair daha fazla ayrıntıya sahip misiniz? Grails'te, 10'un bcrypt için maliyet faktörü / günlük mermileri için varsayılan değer olduğunu fark ettim, bu nedenle öneriniz verildiğinde güncellenmeye değer olabilir.
pm_labs

57
Bcrypt için maliyet faktörü üsteldir veya daha doğrusu 10'luk bir maliyet faktörü 2 ^ 10 mermi (1024), 16'lık bir maliyet faktörü 2 ^ 16 mermi (65536) anlamına gelir. O zaman 5-10 saniye sürmesi doğal. 10'luk bir maliyet faktörünün yaklaşık 64 katı kadar sürmelidir. Diğer yanlış bilgileri temizlemek için PHP'nin crypt işlevi, c'de uygulanan unix crypt kütüphanesini kullanır.
thomasrutter

3
@TJChambers Doğru; hesapta şifreyi ayarlayabilirseniz, kimlik doğrulaması yapabilirsiniz. Parola karma işlemi, bu saldırıyı önlemek için tasarlanmamıştır. Parola tablosuna salt okunur erişimi olan bir saldırganın kimlik doğrulamasının önlenmesi amaçlanmaktadır. Örneğin, üzerinde tablo bulunan bir yedek bant alırsınız.
erickson

8
@LobsterMan Hayır, pek değil. Bir sır saklayabilirseniz, bu yaklaşımı kullanmazsınız, sadece şifreyi saklarsınız. Parola kimlik doğrulama düzenleri, saldırganın bildiğiniz her şeyi keşfettiği varsayımına dayanır. Tuz, her parolanın ayrı ayrı saldırıya uğramasını gerektirmektedir. Parolaları test etmek için gereken hesaplama çabası yinelemelere tabidir. Kullanıcılar iyi şifreler seçerse, tuz açığa çıksa bile güvenli olacaklar. Tuzu gizlemek bazı durumlarda şifresi kötü olan birine yardımcı olabilir, ancak önce şifre kalitesi üzerinde çalışardım.
erickson

1
@NLV bcrypt belirtiminde tanımlanan bir dize:"OrpheanBeholderScryDoubt"
erickson

182

Bu ifadenin şu şekilde ifade edilmesi gerektiğine inanıyorum:

bcrypt, gökkuşağı tablosu saldırılarını önlemek için oluşturulan karmaların içine yerleştirilmiş tuzlara sahiptir .

Yardımcı bcryptprogramın kendisi bir tuz listesi tutuyor gibi görünmüyor. Aksine, tuzlar rastgele oluşturulur ve daha sonra hatırlanmaları için ( Java uygulamasına görebcrypt ) işlevin çıktısına eklenir . Başka bir deyişle, tarafından oluşturulan "karma" sadece karma bcryptdeğildir . Aksine, birleştirilmiş karma ve tuzdur.


20
Tamam, bu yüzden bir siteye kaydoluyorum ve bir şifre "foo" seçiyorum. Bcrypt"akd2! *" rastgele bir tuz ekler, bu da "fooakd2! *" ile sonuçlanır; Daha sonra "bar" parolasıyla oturum açmaya çalışıyorum. Doğru olup olmadığımı görmek için "barakd2! *" Hash'ı gerekir. Tuz başlamak için rastgele oluşturulmuşsa, hashlama ve karşılaştırma işleminden önce onu "bar" a nasıl ekleyeceğini nasıl bilebilir?
Nathan Long

46
@Nathan: bcryptÜretilen çıktıdan (veritabanında saklanan) tuzu nasıl geri çekeceğini bilir. Kimlik doğrulama zamanı geldiğinde bcrypt, orijinal çıktıyı karma ve tuz bileşenlerine ayırır. Tuz bileşeni, kullanıcı tarafından girilen şifreye uygulanır.
Adam Paynter

22
Nathan Long'un yorumuna cevap vermek için bunu düşünmenin iyi bir yolu, tuzların gizli olması anlamına gelmemesidir. Bu nedenle tuz, bcrypt fonksiyonunun çıktısına yukarıda belirtilen cevaplardan biri olarak dahil edilir. Tuz, yaygın parolaların listesi olan gökkuşağı tablolarını veya sadece farklı parolaların kaba kuvvetini vb. Tuz olmadan, A veritabanındaki bir parola karması B veritabanındaki bir parola karmasıyla aynı olacaktır. Tuz, yalnızca hash değerlerini değiştirerek veritabanını çalan birinin parolaların şifresini çözmesini (unhash) zorlaştırır.
Joseph Astrahan

11
@Nathan ancak bir saldırgan tüm şifrelerde bilinen tuzları kaldırabilir ve sonra onlarla bir tablo oluşturabilir mi?
Oscar

3
Bunu şu şekilde anlıyorum: Fikir, her parolanın benzersiz bir tuzu olmasıdır. Tuz, parola karmasına dahil edilir, böylece bir bilgisayar korsanı her parola için bir gökkuşağı tablosu oluşturmak zorunda kalır. Bu, ılımlı bir veritabanı için çok büyük bir zaman alacaktır. Her şey bir saldırganı yavaşlatmak ve böylece kaba-zorlamayı anlamsız yapmakla ilgilidir.
PVermeer

0

İşleri daha da netleştirmek için,

Kayıt / Giriş yönü ->

Parola + tuz, maliyet, tuz ve paroladan oluşturulan bir anahtarla şifrelenir. biz buna şifreli değeri diyoruz cipher text. daha sonra tuzu bu değere ekleriz ve base64 kullanarak kodlarız. maliyeti ekler ve bu üretilen dizedir bcrypt:

$2a$COST$BASE64

Bu değer sonunda saklanır.

Saldırganın parolayı bulmak için ne yapması gerekir? (diğer yön <-)

Saldırganın DB üzerinde kontrol sahibi olması durumunda, saldırgan base64 değerini kolayca deşifre eder ve sonra tuzu görebilir. tuz gizli değildir. rastgele olmasına rağmen. Sonra şifresini çözmek gerekir cipher text.

Daha da önemlisi: Bu işlemde karma yok, CPU pahalı şifreleme - şifre çözme. dolayısıyla gökkuşağı tabloları burada daha az alakalı.


-2

Bu, Spring Security'nin PasswordEncoder arabirim belgelerinden,

 * @param rawPassword the raw password to encode and match
 * @param encodedPassword the encoded password from storage to compare with
 * @return true if the raw password, after encoding, matches the encoded password from
 * storage
 */
boolean matches(CharSequence rawPassword, String encodedPassword);

Bu, kullanıcının bir sonraki girişte tekrar gireceği rawPassword ile eşleşmesi ve daha önceki giriş / kayıt sırasında veritabanında saklanan Bcrypt şifreli şifreyle eşleşmesi gerektiği anlamına gelir.


Bu soruya hiç cevap vermiyor ...
Bcrypt'in
Sitemizi kullandığınızda şunları okuyup anladığınızı kabul etmiş olursunuz: Çerez Politikası ve Gizlilik Politikası.
Licensed under cc by-sa 3.0 with attribution required.