Najlepsze praktyki: solenie i pieprzenie haseł?

Natknąłem się na dyskusję, w której dowiedziałem się, że to, co robiłem, nie było w rzeczywistości soleniem haseł, ale pieprzeniem ich, i od tego czasu zacząłem robić oba z funkcją taką jak:

hash_function($salt.hash_function($pepper.$password)) [multiple iterations]

Ignorując wybrany algorytm haszujący (chcę, żeby to była dyskusja o sole & peppers, a nie konkretnych algorytmach, ale używam bezpiecznego), czy jest to bezpieczna opcja, Czy powinienem robić coś innego? Dla osób nie znających terminów:

  • A sól jest losowo generowana wartość zwykle przechowywana wraz z łańcuchem w bazie danych, mająca na celu uniemożliwienie korzystania z tabel skrótów do łamania haseł. Ponieważ każde hasło ma swój własny salt, wszystkie muszą być indywidualnie wymuszone, aby je złamać; jednak ponieważ salt jest przechowywany w bazie danych z hash hasła, kompromis w bazie danych oznacza utratę obu.

  • A pepper to statyczna wartość przechowywana oddzielnie od bazy danych (Zwykle kodowana na twardo w kod źródłowy aplikacji), który ma być tajny. Jest on używany tak, że kompromis bazy danych nie spowoduje, że cała tabela haseł aplikacji będzie brute-forceable.

Czy jest coś, czego mi brakuje i czy solenie i pieprzenie moich haseł jest najlepszą opcją ochrony bezpieczeństwa mojego użytkownika? Czy jest jakaś potencjalna wada bezpieczeństwa w robieniu tego w ten sposób?

Uwaga: Załóżmy na potrzeby dyskusji, że aplikacja i baza danych są przechowywane na oddzielać maszyny, nie udostępniać haseł itp. tak więc naruszenie serwera bazy danych nie oznacza automatycznie naruszenia serwera aplikacji.

Author: Charles, 2013-06-03

4 answers

Ok. Ponieważ muszę napisać o tym NAD i NAD, zrobię ostatnią kanoniczną odpowiedź na pepper sam.

Pozorna Przewaga Papryki

Wydaje się dość oczywiste, że papryka powinna zwiększyć bezpieczeństwo funkcji hashowych. Jeśli atakujący dostanie tylko twoją bazę danych, hasła użytkowników powinny być bezpieczne, prawda? Wydaje się logiczne, prawda?

Dlatego tak wiele osób uważa, że papryka to dobry pomysł. To "ma sens".

The Rzeczywistość Papryki

W dziedzinie bezpieczeństwa i kryptografii, "make sense" nie wystarczy. Coś musi być udowodnione i mieć sens, aby można było to uznać za bezpieczne. Dodatkowo musi być wdrożony w sposób możliwy do utrzymania. Najbezpieczniejszy system, którego nie można utrzymać, jest uważany za niezabezpieczony (ponieważ jeśli jakakolwiek część tego zabezpieczenia ulegnie awarii, cały system się rozpadnie).

I papryka nie pasuje ani do udowodnionego, ani do utrzymywalnego modelki...

Teoretyczne Problemy Z Papryką

Teraz, gdy już ustawiliśmy scenę, spójrzmy, co jest nie tak z papryką.
  • Podawanie jednego haszu do drugiego może być niebezpieczne.

    W twoim przykładzie robisz hash_function($salt . hash_function($pepper . $password)).

    Z doświadczenia wiemy, że "samo podawanie" jednego wyniku skrótu do innej funkcji skrótu może zmniejszyć ogólne bezpieczeństwo. Powodem jest to, że obie funkcje hash mogą stać się celem ataku.

    Dlatego algorytmy takie jak PBKDF2 używają operacji specjalnych do ich łączenia (w tym przypadku hmac).

    Chodzi o to, że chociaż to nie jest wielka sprawa, to nie jest też trywialna rzecz, aby po prostu rzucać. Systemy kryptograficzne są zaprojektowane tak, aby uniknąć przypadków "powinny działać", a zamiast tego skupić się na przypadkach" zaprojektowanych do pracy".

    Choć może się to wydawać czysto teoretyczne, to tak naprawdę nie jest. Na przykład, Bcrypt nie może akceptować dowolnych haseł. Więc podanie bcrypt(hash(pw), salt) może rzeczywiście spowodować znacznie słabszy hash than bcrypt(pw, salt) if hash() zwraca ciąg binarny.
  • Praca Przeciwko Projektowi

    Sposób, w jaki bcrypt (i inne algorytmy haszujące hasła) zostały zaprojektowane jest do pracy z salt. Koncepcja pieprzu nigdy nie została wprowadzona. To może wydawać się błahostką, ale tak nie jest. Powodem jest to, że sól nie jest tajemnicą. Jest to tylko wartość, która może być znana atakującemu. Pieprz z drugiej strony, z samej definicji jest tajemnicą kryptograficzną.

    Obecny algorytmy hashowania haseł (bcrypt, PBKDF2, itd.) są zaprojektowane tak, aby przyjmować tylko jedną tajną wartość (hasło). Dodanie kolejnej tajemnicy do algorytmu w ogóle nie było badane.

    To nie znaczy, że nie jest bezpieczne. To znaczy, że nie wiemy, czy jest bezpiecznie. A ogólne zalecenie dotyczące bezpieczeństwa i kryptografii jest takie, że jeśli nie wiemy, to nie jest.

    Więc dopóki algorytmy nie zostaną zaprojektowane i zweryfikowane przez kryptografów pod kątem użycia z tajnymi wartościami (peppers), obecne algorytmy nie powinno być z nimi używane.

  • Złożoność Jest Wrogiem Bezpieczeństwa

    Wierz lub nie, złożoność jest wrogiem bezpieczeństwa . Tworzenie algorytmu, który wygląda na złożony, może być bezpieczne lub nie. Ale szanse są dość znaczące, że nie jest bezpieczny.

Istotne Problemy Z Papryką

  • To nie jest możliwe do utrzymania

    Twoja implementacja peppers wyklucza możliwość obróć klucz do pieprzu. Ponieważ pieprz jest używany na wejściu do funkcji jednokierunkowej, nigdy nie można zmienić pieprzu na czas życia wartości. Oznacza to, że musisz wymyślić kilka chytrych hacków, aby umożliwić obracanie klawiszy.

    To jest niezwykle ważne, ponieważ jest wymagane, gdy przechowujesz tajemnice kryptograficzne. Brak mechanizmu obracania kluczy (okresowo i po włamaniu) to ogromna luka w zabezpieczeniach.

    I twój obecny pieprz podejście wymagałoby od każdego użytkownika albo całkowitego unieważnienia hasła przez obrót, albo odczekania do następnego logowania, aby obrócić (co może nigdy nie być)...

    Co sprawia, że Twoje podejście jest natychmiastowe.
  • To Wymaga, Aby Rzucić Własną Krypto

    Ponieważ żaden obecny algorytm nie obsługuje koncepcji Peppera, wymaga on albo komponowania algorytmów, albo wymyślania nowych do obsługi Peppera. A jeśli nie możesz natychmiast zobacz Dlaczego to jest naprawdę złe:

    Każdy, od najgłupszego amatora do najlepszego kryptografa, może stworzyć algorytm, którego sam nie może złamać.

    Nigdy nie rzucaj własnej krypto...

The Better Way

Tak więc, ze wszystkich problemów opisanych powyżej, istnieją dwa sposoby radzenia sobie z sytuacją.

  • Wystarczy Użyć Algorytmów, Ponieważ Exist

    Jeśli poprawnie używasz bcrypt lub scrypt (przy wysokim koszcie), wszystkie hasła słownikowe oprócz najsłabszych powinny być statystycznie bezpieczne. Aktualny rekord hashowania bcrypt w cenie 5 to 71K hashów na sekundę. Przy takim tempie nawet 6-znakowe losowe hasło zajęłoby lata, aby złamać. A biorąc pod uwagę, że mój minimalny zalecany koszt to 10, to zmniejsza hasze na sekundę o współczynnik 32. Czyli mówimy tylko o 2200 hashach na sekundę. W tym tempie nawet jakiś słownik frazy lub modyfikacje mogą być bezpieczne.

    Dodatkowo powinniśmy sprawdzać te słabe klasy haseł przy drzwiach i nie wpuszczać ich do środka. Ponieważ łamanie haseł staje się bardziej zaawansowane, wymagania dotyczące jakości haseł również powinny być spełnione. To wciąż gra statystyczna, ale przy odpowiedniej technice przechowywania i silnych hasłach każdy powinien być praktycznie bardzo bezpieczny...

  • Zaszyfruj Hash Wyjściowy Przed Przechowywaniem

    Istnieje w sferze bezpieczeństwa algorytm zaprojektowany do obsługi wszystkiego, co powiedzieliśmy powyżej. To szyfr blokowy. Jest dobry, ponieważ jest odwracalny, więc możemy obracać klucze (yay! konserwacja!). Jest dobry, ponieważ jest używany zgodnie z projektem. Jest to dobre, ponieważ nie daje użytkownikowi żadnych informacji.

    Spójrzmy jeszcze raz na tę linię. Załóżmy, że atakujący zna Twój algorytm (który jest wymagany dla bezpieczeństwa, w przeciwnym razie jest to bezpieczeństwo przez zaciemnienie). Przy tradycyjnym podejściu do pieprzu atakujący może stworzyć hasło sentinel, a ponieważ zna sól i wydajność, może brutalnie zmusić pieprz. To ryzykowne, ale możliwe. Za pomocą szyfru napastnik nic nie dostanie. A ponieważ sól jest randomizowana, hasło sentinel nawet mu nie pomoże. Najlepsze, co im pozostaje, to zaatakować zaszyfrowaną formę. Oznacza to, że najpierw muszą zaatakować twój zaszyfrowany hash, aby odzyskać klucz szyfrowania, a następnie zaatakować hasze. Ale jest wiele badań nad atakowanie szyfrów, więc chcemy na tym polegać.

TL/DR

Nie używaj papryki. Istnieje wiele problemów z nimi i są dwa lepsze sposoby: nieużywanie tajemnicy po stronie serwera (tak, jest w porządku) i szyfrowanie wyjściowego hasha za pomocą szyfru blokowego przed przechowywaniem.
 275
Author: ircmaxell,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2017-05-23 12:10:06

Pięść powinniśmy mówić o dokładnej przewadze pieprzu :

    Pepper może chronić słabe hasła przed atakiem słownikowym, w szczególnym przypadku, gdy atakujący ma dostęp do bazy danych (zawierającej hasze), ale nie ma dostępu do kodu źródłowego za pomocą pepper.

Typowy scenariusz to SQL-injection, wyrzucane kopie zapasowe, wyrzucane serwery... Sytuacje te nie są tak rzadkie, jak się wydaje, i często nie są pod kontrolą (serwer-hosting). Jeśli używasz...

  • unikalna sól na hasło
  • powolny algorytm hashowania, taki jak BCrypt

...silne hasła są dobrze chronione. To prawie niemożliwe, aby brute force silne hasło w tych warunkach, nawet jeśli sól jest znana. Problemem są słabe hasła, które są częścią słownika brute-force lub są ich pochodnymi. Atak słownikowy ujawni je bardzo szybko, ponieważ testujesz tylko najczęstsze hasła.

Drugie pytanie brzmi Jak zastosować pieprz?

Często zalecanym sposobem zastosowania pieprzu jest połączenie hasła i pieprzu przed przekazaniem go do funkcji hash:

$pepperedPassword = hash_hmac('sha512', $password, $pepper);
$passwordHash = bcrypt($pepperedPassword);
Jest jednak jeszcze lepszy sposób:
$passwordHash = bcrypt($password);
$encryptedHash = encrypt($passwordHash, $serverSideKey);

To nie tylko pozwala na dodanie tajemnicy po stronie serwera, ale także pozwala na wymianę $serverSideKey, jeśli jest to konieczne. Metoda ta wymaga nieco więcej pracy, ale jeśli kod raz istnieje (Biblioteka) nie ma powodu, aby go nie używać.

 18
Author: martinstoeckli,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-03 09:48:34

Celem soli i pieprzu jest zwiększenie kosztów wstępnie obliczonego wyszukiwania hasła, zwanego tęczową tabelą.

Ogólnie znalezienie kolizji dla pojedynczego hasha jest trudne (zakładając, że hash jest bezpieczny). Jednak przy krótkich hashach możliwe jest użycie komputera do wygenerowania wszystkich możliwych hashów na dysku twardym. To się nazywa Tęczowy stół. Jeśli stworzysz tęczową tabelę, możesz wyjść w świat i szybko znaleźć wiarygodne hasła dla każdego (unsolted unpepered) hash.

Celem Peppera jest uczynienie tęczowej tabeli potrzebnej do zhakowania listy haseł wyjątkowym. Tracąc tym samym więcej czasu na atakującego, aby skonstruować Tęczowy stół.

Celem salt jest jednak, aby rainbow table dla każdego użytkownika był unikalny dla użytkownika, co dodatkowo zwiększa złożoność ataku.

Naprawdę celem bezpieczeństwa komputerowego jest prawie nigdy nie uczynienie tego (matematycznie) niemożliwym, tylko matematycznie i fizycznie niepraktyczne (np. w bezpiecznych systemach do obliczenia hasła pojedynczego użytkownika potrzeba całej entropii we wszechświecie (i nie tylko)).

 2
Author: Aron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-03 07:32:12

Nie widzę zapisywania zakodowanej na twardo wartości w kodzie źródłowym jako mającej jakiekolwiek znaczenie dla bezpieczeństwa. To ochrona przez ciemność.

Jeśli haker zdobędzie twoją bazę danych, będzie mógł rozpocząć brutalne wymuszanie haseł użytkowników. Haker szybko zidentyfikuje Twój pieprz, jeśli uda mu się złamać kilka haseł.

 1
Author: Sven,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/doraprojects.net/template/agent.layouts/content.php on line 54
2013-06-03 07:23:06