Pytanie:
Zalecana liczba iteracji podczas korzystania z PKBDF2-SHA256?
Tails
2011-05-20 03:32:55 UTC
view on stackexchange narkive permalink

Ciekaw jestem, czy ktoś ma jakieś rady lub punkty odniesienia, jeśli chodzi o określenie, ile iteracji jest „wystarczająco dobrych” podczas korzystania z PBKDF2 (szczególnie z SHA-256). Z pewnością „wystarczająco dobre” jest subiektywne i trudne do zdefiniowania, różni się w zależności od profilu ryzyka &, a to, co jest „wystarczająco dobre” dzisiaj, prawdopodobnie nie będzie „wystarczająco dobre” jutro ...

Pozostaje jednak pytanie co przemysł uważa obecnie za „wystarczająco dobre”? Jakie punkty odniesienia są dostępne do porównania?

Niektóre źródła, które znalazłem:

  • Wrzesień 2000 - zalecane ponad 1000 rund (źródło: RFC 2898)
  • luty 2005 - AES w Kerberos 5 „domyślnie” wynosi 4096 rund SHA-1. (źródło: RFC 3962)
  • wrzesień 2010 - ElcomSoft twierdzi, że iOS 3.x używa 2000 iteracji, iOS 4.x używa 10000 iteracji, pokazuje, że BlackBerry używa 1 (dokładny algorytm haszowania nie jest określony) (źródło: ElcomSoft)
  • maj 2011 - LastPass używa 100 000 iteracji SHA-256 (źródło: LastPass)
  • czerwiec 2015 - StableBit używa 200 000 iteracji SHA-512 (źródło: StableBit CloudDrive Nuts & Bolts)
  • Sierpień 2015 - CloudBerry używa 1000 iteracji SHA-1 (źródło: CloudBerry Lab Security Consideration (pdf))

Byłbym wdzięczny za wszelkie dodatkowe odniesienia lub opinie na temat tego, w jaki sposób ustaliłeś, ile iteracji było „wystarczająco dobrych” dla Twojej aplikacji.

Jako dodatkowe tło rozważam PBKDF2-SHA256 jako metodę używaną do haszowania haseł użytkowników w celu przechowywania w bezpiecznej witrynie internetowej. Moja planowana sól PBKDF2 to: losowa sól na użytkownika (przechowywana w przejrzystym miejscu z każdym rekordem użytkownika) XOR z solą globalną. Celem jest zwiększenie kosztów brutalnego wymuszania haseł i uniknięcie ujawniania par użytkowników z identycznymi hasłami.

Odniesienia:

  • RFC 2898: PKCS # 5: Password- Based Cryptography Specification v2.0
  • RFC 3962: Advanced Encryption Standard (AES) Encryption for Kerberos 5
  • PBKDF2: funkcja wyprowadzania klucza na podstawie hasła v2
Chociaż oznaczam to jako odpowiedź, nadal będę wdzięczny za wszelkie odniesienia, które dokumentują liczbę iteracji używanych przez inne aplikacje ... Dzięki.
Globalna sól nie zapewnia dodatkowej ochrony przed tęczowymi stołami. Jeśli używasz globalnej soli do zapobiegania próbom łamania zabezpieczeń offline, możesz [rozważyć użycie HMAC] (http://security.stackexchange.com/questions/19243/should-password-hashes-be-encrypted-or -hmaced) zamiast tego. Rozważ również użycie bcrypt lub scrypt zamiast PBKDF2-SHA256, ponieważ zostały one zaprojektowane z wyraźnym celem powolnego haszowania haseł.
Uwaga obowiązkowa dla wszystkich, którzy tu przyjeżdżają: W dzisiejszych czasach należy poważnie rozważyć użycie lepszych algorytmów rozciągania kluczy niż PKBDF2, ponieważ jest to wysoce parralisowalne. Potraktuj [Argon2] (https://en.wikipedia.org/wiki/Argon2) jako najnowszą rzecz (zwycięzca z 2015 r.) Lub scrypt lub coś podobnego.
Pięć odpowiedzi:
#1
+239
Thomas Pornin
2011-05-20 17:43:14 UTC
view on stackexchange narkive permalink

W aplikacji należy stosować maksymalną liczbę rund, która jest dopuszczalna pod względem wydajności. Liczba rund jest czynnikiem spowolnienia, którego używasz na podstawie tego, że w normalnych warunkach użytkowania takie spowolnienie ma na Ciebie znikomy wpływ (użytkownik go nie zobaczy, dodatkowy koszt procesora nie oznacza zakupu większego serwera, a wkrótce). To w dużej mierze zależy od kontekstu operacyjnego: jakie maszyny są zaangażowane, ile uwierzytelnień użytkowników na sekundę ... więc nie ma jednej odpowiedzi dla wszystkich.

Szeroki obraz wygląda następująco:

  • Czas weryfikacji pojedynczego hasła w systemie wynosi v . Możesz dostosować ten czas, wybierając liczbę rund w PBKDF2.
  • Potencjalny napastnik może zebrać f razy więcej mocy procesora niż Ty (np. Masz pojedynczy serwer, a atakujący ma 100 dużych komputerów, z których każdy jest dwa razy szybszy od twojego serwera: prowadzi to do f=200).
  • Przeciętny użytkownik ma hasło o entropii n bity (oznacza to, że próba odgadnięcia hasła użytkownika ze słownikiem „wiarygodnych haseł” zajmie średnio 2n-1 prób).
  • Atakujący uzna Twój system za warty ataku, jeśli przeciętne hasło może zostać złamane w czasie krótszym niż p (to jest „cierpliwość” atakującego).

Twoim celem jest sprawienie, aby średni koszt złamania jednego hasła przewyższył cierpliwość atakującego, tak aby nawet nie próbował i zaczął koncentrować się na innym, łatwiejszym celu. Dzięki opisom wyszczególnionym powyżej oznacza to, że chcesz:

v · 2 n-1 > f · p

p jest poza twoją kontrolą; można ją oszacować na podstawie wartości danych i systemów chronionych hasłami użytkowników. Powiedzmy, że p to jeden miesiąc (jeśli zajmie to więcej niż miesiąc, atakujący nie będzie się fatygował). Możesz zmniejszyć f , kupując większy serwer; z drugiej strony, atakujący będzie próbował zwiększyć f , kupując większe maszyny. Kłopotliwe jest to, że łamanie haseł jest zadaniem żenująco równoległym, więc osoba atakująca otrzyma duże przyspieszenie, używając GPU, który obsługuje ogólne programowanie; więc typowe f będzie nadal wynosić kilkaset.

n odnosi się do jakości haseł, na które w jakiś sposób możesz wpłynąć poprzez rygorystyczną politykę doboru haseł, ale realistycznie rzecz biorąc, trudno będzie uzyskać wartość n powyżej, powiedzmy, 32 bitów. Jeśli spróbujesz wymusić silniejsze hasła, użytkownicy zaczną z tobą aktywnie walczyć, stosując obejścia, takie jak ponowne używanie haseł z innego miejsca, zapisywanie haseł na karteczkach itp.

Zatem pozostały parametr to v . Mając f = 200 (atakujący z kilkunastoma dobrymi GPU), miesięczną cierpliwość i n = 32 , potrzebujesz v , wynosić co najmniej 241 milisekund (uwaga: początkowo napisałem tutaj „8 milisekund”, co jest błędne - jest to liczba dla cierpliwości jednego dnia zamiast jednego miesiąca). Więc powinieneś ustawić liczbę rund w PBKDF2 tak, aby obliczenie go na jednym haśle zajmowało co najmniej tyle czasu na twoim serwerze. Nadal będziesz w stanie zweryfikować cztery hasła na sekundę z jednym rdzeniem, więc wpływ na procesor jest prawdopodobnie znikomy (*). W rzeczywistości bezpieczniej jest używać większej liczby rund, ponieważ, spójrzmy prawdzie w oczy, uzyskanie 32-bitowej wartości entropii z hasła przeciętnego użytkownika jest nieco optymistyczne; Z drugiej strony, w niewielu atakach dziesiątki komputerów w ciągu jednego miesiąca zostaną przeznaczone na złamanie jednego hasła, więc może „cierpliwość atakującego” jednego dnia jest bardziej realistyczna, co prowadzi do kosztu weryfikacji hasła wynoszącego 8 milisekund.

Więc musisz zrobić kilka testów porównawczych. Ponadto powyższe działa tak długo, jak długo implementacja PBKDF2 / SHA-256 jest szybka. Na przykład, jeśli używasz implementacji w pełni opartej na C # / Javie, uzyskasz typowy współczynnik spowolnienia 2 do 3 (w porównaniu do C lub zestawu) dla zadań intensywnie wykorzystujących procesor; w zapisach powyżej jest to równoważne pomnożeniu f przez 2 lub 3. Dla porównania, procesor Core2 2,4 GHz może wykonać około 2,3 miliona podstawowych obliczeń SHA-256 na sekundę (przy pojedynczym rdzeń), więc oznaczałoby to, że na tym procesorze około 20000 rund, aby osiągnąć cel „8 milisekund”.


(*) Uważaj, aby weryfikacja hasła była droższa, a serwer bardziej podatne na ataki typu Denial-of-Service. Powinieneś zastosować kilka podstawowych środków zaradczych, takich jak tymczasowe umieszczenie na czarnej liście adresów IP klientów, które wysyłają zbyt wiele żądań na sekundę. Mimo wszystko musisz to zrobić, aby udaremnić ataki słownikowe online .

+1 za świetną odpowiedź, gdybym mógł, dałbym kolejne +1 za żenująco równoległe łącze :-)
To świetny sposób na myślenie o tym - dzięki!
Tylko pomysł: czy można zrobić około 20 000 rund na komputerze klienckim i 1 000 na serwerze? Gdyby atakujący zaczął odgadnąć „normalne hasła”, nadal musiałby wykonać 21 tys. Rund. A gdyby zaczął od kluczy, musiałby zrobić tylko 1000 rund, ale entropia powinna być znacznie wyższa. Czy coś mi brakuje? Wydaje mi się, że to dobre rozwiązanie.
@cooky451:, możesz to zrobić, ale może to być trudne do skonfigurowania. Klienci mogą korzystać z szerokiej gamy sprzętu, z których niektóre są bardzo słabe, jeśli chodzi o przetwarzanie. Ponadto w kontekście sieciowym oznacza to Javascript, a implementacja PBKDF2 _Javascript_ nie da wielu iteracji (_ działałaby_ znacznie lepiej z apletem Java, ale to kolejna puszka robaków).
Nie rozumiem, jak w swoim przykładzie doszło do 8 ms. Jeśli f = 200, p = 30 * 24 * 60 * 60 * 1000 ?, n = 32. Wtedy v jest 241 ms? Przekształciłem 1 miesiąc w milis. Nie wiem, co robię źle. Dziękuję za odpowiedź
To wychodzi do 241 ms. W rzeczywistości, jeśli włączysz 8 ms do formuły, otrzymasz około 23 godzin jako „cierpliwość napastnika”. To o wiele mniej niż miesiąc (dla pojedynczego 32-bitowego hasła entropii) ... I wystarczająco niskie, aby prawdopodobnie zwiększyć zalecaną wartość 8 ms.
Oto krótki skrypt do benchmarkingu PBKDF2 (uwaga: czas podawany jest w sekundach): https://gist.github.com/sarciszewski/a3b1cf19caab3f408bf8
Zgadzam się z twoją oceną, z jednym wyjaśnieniem: liczba iteracji nie powinna być oparta na tym, ile czasu zajmie * twojemu * sprzętowi wykonanie operacji.Musi być oparty na ilości czasu, przez jaki * atakujący * sprzęt może wykonać operację.Jeśli masz słaby sprzęt, nie jest to dobra wymówka dla wyboru „iteracji = 1”.Twoje długie wyjaśnienie opisuje to w rozsądny sposób, ale Twój wstępny wniosek brzmi: „na tyle, na ile uważasz, że jest w porządku w Twoim środowisku”.To naprawdę powinno być „wszystko, czego potrzeba, aby udaremnić napastnika w jego otoczeniu”.
Uaktualniamy szyfrowanie w naszej istniejącej aplikacji.Jednak wysoka iteracja spowoduje ogromny spadek wydajności, ponieważ nasz system czasami musi radzić sobie z szyfrowaniem / odszyfrowywaniem tysięcy wpisów.Wygląda więc na to, że będziemy musieli użyć bardzo niskiej wartości iteracji - prawdopodobnie nie więcej niż 1000.Więc mam pytanie, czy powinniśmy w ogóle zawracać sobie głowę tak niską wartością?Dlaczego po prostu nie wybrać „1”?
#2
+33
rook
2011-05-20 04:00:30 UTC
view on stackexchange narkive permalink

Uruchom openssl speed w wierszu poleceń, aby zorientować się, jak szybkie są funkcje skrótu wiadomości. Potrafię obliczyć około 1,6 miliona haszów sha256 na sekundę lub około 145 miliardów prób dziennie na moim czterordzeniowym moście 2,2 GHz. Jeśli ktoś ma hasło, które jest w słowniku języka angielskiego i użył jednej rundy sha256, ładowanie listy słów z dysku zajmie więcej czasu niż iteracja po liście, aby złamać hash. Gdybyś zrobił PKBDF2-SHA256 z kilkuset tysiącami nabojów, przebicie zajęłoby kilka minut. Egzekwowanie polityki silnych haseł pomaga, bardzo .

Prawdziwa odpowiedź: ile czasu masz na spalenie?

Słuszne uwagi. prędkość openssl - fajnie! Ale przy 200 000 rund, przy 2 M na sekundę, to tylko 10 na sekundę. Mały słownik ze stu tysiącami słów zajmie kilka godzin. Ale tak, nawet przy wielu rundach złe hasło jest złe ....
Naprawiono @Michael.
#3
+17
nealmcb
2011-05-21 00:53:20 UTC
view on stackexchange narkive permalink

Odpowiedź Thomasa dostarcza pomocnego modelu bazowego i danych. Ale cel, jaki sobie stawia, nie ma dla mnie sensu. Typowy napastnik nie pozna liczby iteracji, dopóki faktycznie nie włamie się do witryny i nie złapie bazy danych skrótów. Po wykonaniu tej czynności nie przejdą dalej tylko dlatego, że używasz dużej liczby iteracji. Będą próbować złamać tyle, ile tylko mogą, i całkiem możliwe, że opublikują skróty, aby inni nadal próbowali je złamać przez lata z coraz potężniejszym sprzętem. Tak więc „p” i „f” będą rosły długo po włamaniu.

Poza tym prawdziwe hasła użytkowników nie są dobrze modelowane przez miarę złożoności, taką jak 32 bity entropii. W tym względzie pomocny jest artykuł Bezpieczeństwo wielokrotnego użytku: nowa publikacja o metrykach bezpieczeństwa haseł i dokumentuje to, co wiemy od dawna: wielu użytkowników wybiera hasła łatwe do odgadnięcia, a istnieje długi ogon. Oznacza to również, że napastnicy zawsze znajdą jakieś, jeśli będą wystarczająco się postarać.

Powiedziałbym, że bardziej prawdopodobnym celem byłaby ochrona jak największego odsetka użytkowników przed złamaniem haseł. Na przykład. Tabela 4.2.1 w PDF pokazuje, że jeśli udało Ci się ograniczyć napastnika podczas jakiejś kampanii ataku ze średnio 1 miliona prób na hash do 500 000 prób, możesz chronić hasła 5% Twoi użytkownicy (zakładając, że jest to mieszanka haseł składających się z więcej niż 7 znaków niż hasła składające się z ponad 8 znaków, co zmniejsza odsetek złamanych haseł z 35% do 30%). Oczywiście dokładny kształt krzywej i miejsce, w którym się na niej znajdują, będzie się znacznie różnić.

Więc wybrałbym maksymalną liczbę iteracji, na którą możesz zaplanować budżet, o ile nie opóźni się prawdziwi użytkownicy wykonujący normalne logowanie. I powinieneś zwiększać tę wartość wraz ze wzrostem mocy obliczeniowej na przestrzeni lat.

#4
+3
Martin Thoma
2019-06-01 11:57:06 UTC
view on stackexchange narkive permalink

Potraktuj to jako bardzo długi komentarz. Byłem ciekawy, jak szybko wszystko działa na moim osobistym laptopie (Thinkpad T460p, Intel i7-6700HQ). Wiem, że do łamania zasolonych haseł są specjalne urządzenia, ale jeśli masz usługę internetową, prawdopodobnie nie masz do tego specjalnego sprzętu.

Wyniki oceny

Wartość domyślna werkzeug.security.generate_password_hash obecnie (01.06.2019) to pbkdf2:sha256:150000.

Jak możesz Widzisz, czas wykonania rośnie liniowo wraz z liczbą rund / iteracji. Oznacza to, że wartość domyślna na moim komputerze trwa około 281 ms.

enter image description here

enter image description here

  sha512, 1 iteracja: min: 67,1μs, średnia: 72,2μs, max: 310,9μssha512, 15000 iteracji: min: 38462,8μs, średnia: 40291,2μs, max: 44842,4μssha256, 15000 iteracji: min: 27167,6μs, średnia: 28118,0μs, max: 30826,0μssha512, 1000 iteracji: min: 2636,7μs, średnia: 2694,3μs, max: 3579,0μssha256, 1000 iteracji: min: 1870,7μs, średnia: 1888,8μs, max: 2477,0μsmd5, 15000 iteracja: min: 21126,2μs, średnia: 21864,8μs, max: 23799,3μssha512, 1 iteracja: min: 23,4μs, średnia: 26,9μs, max: 40,6μssha512, 1000 iteracji: min: 2586,7μs, średnia: 2761,1μs, max: 3120,6μssha256, 1000 iteracji: min: 1823,3μs, średnia: 1834,6μs, max: 2008,5μssha512, 15000 iteracji: min: 38507,9μs, średnia: 40210,8μs, max: 47430,3μssha256, 15000 iteracji: min: 27257,1μs, średnia: 28454,0 μs, maks .: 31213,5 μsmd5, 15000 iteracji: min: 21219,9 μs, średnia: 21842,4 μs, maks .: 24305,0 μs  

C ode

#5
+1
ModernMachine
2012-06-19 20:48:48 UTC
view on stackexchange narkive permalink

Nowoczesna maszyna wyposażona w 8 procesorów graficznych obecnej generacji będzie obliczać wartość rzędu 9 miliardów SHA-256 na sekundę, czyli około 777 bilionów haszów dziennie, a te GPU mogą wykonywać ataki słownikowe oparte na regułach.

W ramach aktualizacji, w październiku 2014 r., Na [https://hashcat.net/oclhashcat/](https://hashcat.net/oclhashcat/), szybkości osiągały do ​​12,3 miliarda SHA-256 hashów na sekundę (i 4,5 miliarda SHA-512 na sekundę) dla tej maszyny z 8 GPU, przy użyciu procesorów graficznych AMD R9 290X.
Jakie są teraz zaktualizowane statystyki?
na https://gist.github.com/epixoip/a83d38f412b4737e99bbef804a270c40 SHA-256 ~ 23 miliardy hashów na sekundę, SHA-512 ~ 8,6 miliarda hashów na sekundę, przy użyciu 8x Nvidia GTX 1080


To pytanie i odpowiedź zostało automatycznie przetłumaczone z języka angielskiego.Oryginalna treść jest dostępna na stackexchange, za co dziękujemy za licencję cc by-sa 3.0, w ramach której jest rozpowszechniana.
Loading...