W jaki sposób bcrypt może mieć wbudowane sole?

616

Artykuł Cody Hale „Jak bezpiecznie przechowywać hasło” twierdzi, że:

bcrypt ma wbudowane sole, aby zapobiec atakom na tęczowy stół.

Cytuje ten artykuł , który mówi, że w implementacji OpenBSD bcrypt:

OpenBSD generuje 128-bitową sól bcrypt ze strumienia klucza arcfour (arc4random (3)), zaszczepionego losowymi danymi zbieranymi przez jądro z taktowania urządzenia.

Nie rozumiem, jak to może działać. W mojej koncepcji soli:

  • Musi być inny dla każdego przechowywanego hasła, aby dla każdego trzeba było wygenerować osobną tęczową tabelę
  • Musi być gdzieś przechowywany, aby był powtarzalny: gdy użytkownik próbuje się zalogować, podejmujemy próbę podania hasła, powtarzamy tę samą procedurę „salt and and hash”, którą wykonaliśmy, kiedy pierwotnie zapisaliśmy jego hasło, i porównujemy

Kiedy używam Devise (menedżera logowania do Railsów) z bcryptem, w bazie danych nie ma kolumny soli, więc jestem zdezorientowany. Jeśli sól jest losowa i nigdzie nie jest przechowywana, jak możemy w wiarygodny sposób powtórzyć proces mieszania?

Krótko mówiąc, w jaki sposób bcrypt może mieć wbudowane sole ?

Nathan Long
źródło

Odpowiedzi:

789

To jest bcrypt:

Wygeneruj losową sól. Współczynnik „kosztu” został wstępnie skonfigurowany. Zbierz hasło.

Uzyskaj klucz szyfrujący na podstawie hasła, używając współczynnika soli i kosztu. Użyj go do zaszyfrowania znanego ciągu. Przechowuj koszt, sól i tekst zaszyfrowany. Ponieważ te trzy elementy mają znaną długość, łatwo je połączyć i przechowywać w jednym polu, ale później można je rozdzielić.

Gdy ktoś próbuje się uwierzytelnić, odzyskaj przechowywany koszt i sól. Wyprowadź klucz z hasła wejściowego, kosztu i soli. Zaszyfruj ten sam dobrze znany ciąg. Jeśli wygenerowany tekst zaszyfrowany jest zgodny z zapisanym tekstem zaszyfrowanym, hasło jest zgodne.

Bcrypt działa w bardzo podobny sposób do bardziej tradycyjnych schematów opartych na algorytmach takich jak PBKDF2. Główną różnicą jest użycie klucza pochodnego do szyfrowania znanego zwykłego tekstu; inne schematy (rozsądnie) zakładają, że funkcja wyprowadzania klucza jest nieodwracalna i przechowują uzyskany klucz bezpośrednio.


Przechowywany w bazie danych bcrypt„skrót” może wyglądać mniej więcej tak:

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

W rzeczywistości są to trzy pola rozdzielone znakiem „$”:

  • 2aokreśla bcryptużywaną wersję algorytmu.
  • 10jest czynnikiem kosztów; Wykorzystano 2 10 iteracji funkcji wyprowadzania klucza (a propos, to nie wystarczy. Polecam koszt 12 lub więcej.)
  • vI8aWBnW3fID.ZQ4/zo1G.q1lRps.9cGLcZEiGDMVr5yUP1KUOYTato sól i tekst szyfrowany, połączone i zakodowane w zmodyfikowanym Base-64. Pierwsze 22 znaki dekodują do 16-bajtowej wartości soli. Pozostałe znaki to tekst zaszyfrowany do porównania w celu uwierzytelnienia.

Ten przykład pochodzi z dokumentacji implementacji ruby ​​Cody Hale.

erickson
źródło
7
Czy miałbyś więcej szczegółów, dlaczego współczynnik kosztu 10 nie wystarczyłby? W Grails zauważyłem, że 10 jest wartością domyślną dla współczynnika kosztu / dzienników dla bcrypt, więc może warto zaktualizować, biorąc pod uwagę twoją sugestię.
pm_labs
57
Współczynnik kosztów dla bcrypt jest wykładniczy, a raczej współczynnik kosztu 10 oznacza 2 ^ 10 rund (1024), współczynnik kosztu 16 oznacza 2 ^ 16 rund (65536). To naturalne, że zajęłoby to 5-10 sekund. Powinno to zająć około 64 razy dłużej niż współczynnik kosztu 10. Aby usunąć inne błędne informacje, funkcja kryptograficzna PHP wykorzystuje unikatową bibliotekę krypt, która jest zaimplementowana w c.
thomasrutter
3
@TJChambers Zgadza się; jeśli możesz ustawić hasło do konta, będziesz mógł się uwierzytelnić. Mieszanie hasła nie ma na celu zapobiec temu atakowi. Ma to na celu zapobieżenie uwierzytelnieniu osoby atakującej z dostępem tylko do odczytu do tabeli haseł. Na przykład otrzymasz kopię zapasową taśmy ze stołem na niej.
erickson,
8
@LobsterMan Nie, nie bardzo. Gdybyś mógł zachować tajemnicę, nie użyłbyś tego podejścia, po prostu przechowałeś hasło. Schematy uwierzytelniania haseł oparte są na założeniu, że atakujący odkrył wszystko, co wiesz. Sól wymaga, aby każde hasło było atakowane indywidualnie. Wysiłek obliczeniowy wymagany do testowania haseł zależy od iteracji. Jeśli użytkownicy wybiorą dobre hasła, będą bezpieczne, nawet jeśli ujawni się sól. Ukrywanie soli może pomóc w niektórych przypadkach złemu hasłu, ale najpierw pracowałbym nad jakością hasła.
erickson
1
@NLV Jest to ciąg zdefiniowany w specyfikacji bcrypt:"OrpheanBeholderScryDoubt"
erickson
181

Uważam, że to zdanie powinno być sformułowane w następujący sposób:

bcrypt ma wbudowane sole w generowane skróty, aby zapobiec atakom na tęczą.

Samo bcryptnarzędzie nie wydaje się utrzymywać listy soli. Przeciwnie, sole są generowane losowo i dołączane do wyniku funkcji, aby były później zapamiętywane (zgodnie z implementacją Javabcrypt ). Innymi słowy, „skrót” generowany przez bcryptto nie tylko skrót. Jest to raczej skrót i sól połączona.

Adam Paynter
źródło
20
OK, więc zapisuję się na stronę i wybieram hasło „foo”. Bcryptdodaje losową sól „akd2! *”, co skutkuje „fooakd2! *”, który jest mieszany i zapisywany. Później próbuję zalogować się przy użyciu hasła „bar”. Aby sprawdzić, czy mam rację, musi haszować „barakd2! *”. Jeśli sól została wygenerowana losowo na początek, skąd wie, jak dodać ją z powrotem do „paska” przed mieszaniem i porównywaniem?
Nathan Long
46
@Nathan: bcryptumie odzyskać sól z wygenerowanego wyjścia (które jest przechowywane w bazie danych). Kiedy przychodzi czas na uwierzytelnienie, bcryptdzieli oryginalne dane wyjściowe na składniki hash i salt. Komponent soli jest stosowany do hasła przychodzącego wpisanego przez użytkownika.
Adam Paynter
22
Aby odpowiedzieć na komentarz Nathana Longa, dobrym sposobem myślenia o tym jest to, że sole nie mają być tajemnicą. Dlatego sól jest zawarta w danych wyjściowych funkcji bcrypt jako jedna z odpowiedzi wskazanych powyżej. Sól ma zapobiegać tęczowym tabelom, które są listami popularnych haseł lub po prostu brutalną siłą itp. Różnych haseł, ale mieszane. Bez soli skrót dla hasła w bazie danych A byłby taki sam jak skrót dla hasła w bazie danych B. Sól po prostu zmienia wartości skrótu, co utrudnia osobie, która ukradła bazę danych, odszyfrowanie (odblokowanie) haseł.
Joseph Astrahan
11
@Nathan, ale czy osoba atakująca może po prostu usunąć znane sole ze wszystkich haseł, a następnie utworzyć z nimi tabelę?
Oscar
3
Tak to rozumiem: Chodzi o to, że każde hasło ma unikalną sól. Sól zawarta w haszu hasła, więc haker musiałby utworzyć tęczową tabelę dla każdego hasła. Zajmie to ogromną ilość czasu dla umiarkowanej bazy danych. Chodzi o spowolnienie atakującego, a tym samym uczynienie brutalnego wymuszania bezcelowym.
PVermeer
0

Aby wszystko było jeszcze jaśniejsze,

Rejestracja / Kierunek logowania ->

Hasło + sól jest szyfrowane kluczem generowanym z: kosztu, soli i hasła. nazywamy to zaszyfrowaną wartością cipher text. następnie dołączamy sól do tej wartości i kodujemy ją za pomocą base64. dołączenie do niego kosztu i jest to wytworzony ciąg z bcrypt:

$2a$COST$BASE64

Ta wartość jest ostatecznie przechowywana.

Co musiałby zrobić atakujący, aby znaleźć hasło? (inny kierunek <-)

W przypadku, gdy atakujący przejmie kontrolę nad bazą danych, atakujący łatwo zdekoduje wartość base64, a następnie będzie mógł zobaczyć sól. sól nie jest tajemnicą. chociaż jest losowy. Następnie będzie musiał odszyfrować cipher text.

Co ważniejsze: w tym procesie nie ma nic wspólnego, a raczej kosztowne szyfrowanie procesora - deszyfrowanie. dlatego tabele tęczy są tutaj mniej odpowiednie.

jony89
źródło
-2

Pochodzi z dokumentacji interfejsu PasswordEncoder firmy Spring Security,

 * @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);

Co oznacza, że ​​trzeba będzie dopasować rawPassword, które użytkownik wprowadzi ponownie przy następnym logowaniu i dopasuje je do hasła zakodowanego w Bcrypt, które jest przechowywane w bazie danych podczas poprzedniego logowania / rejestracji.

Poznaj Shah
źródło
To wcale nie odpowiada na pytanie ... Nie mówi nic o tym, jak bcrypt może mieć wbudowane sole
spencer.sm