Aktualizacja: Proszę zauważyć, że nie pytam, czym jest sól, czym jest tęczowy stół, czym jest atak słownikowy ani jaki jest cel soli. Pytam: Jeśli znasz sól i hash użytkowników, czy nie jest łatwo obliczyć ich hasło?
Rozumiem ten proces i sam go wdrażam w niektórych swoich projektach.
s = random salt
storedPassword = sha1(password + s)
W bazie danych, którą przechowujesz:
username | hashed_password | salt
Każda implementacja solenia, którą widziałem, dodaje sól na końcu hasła lub na początku:
hashed_Password = sha1(s + password )
hashed_Password = sha1(password + s)
Dlatego atak słownikowy hakera, który jest wart swojej soli (ha ha), po prostu skierowałby każde słowo kluczowe przeciwko przechowywanym solom w typowych kombinacjach wymienionych powyżej.
Z pewnością implementacja opisana powyżej po prostu dodaje kolejny krok dla hakera, bez faktycznego rozwiązania podstawowego problemu? Jakie są alternatywy, aby obejść ten problem, czy też nie rozumiem problemu?
Jedyne, o czym mogę pomyśleć, to mieć tajny algorytm mieszania, który łączy sól i hasło w losowy wzór lub dodaje inne pola użytkownika do procesu haszowania, co oznacza, że haker musiałby mieć dostęp do bazy danych ORAZ kod, aby zasznurować aby atak słownikowy okazał się owocny. (Aktualizacja, jak wskazano w komentarzach, najlepiej założyć, że haker ma dostęp do wszystkich twoich informacji, więc prawdopodobnie nie jest to najlepsze).
Podam przykład, w jaki sposób proponuję hakerowi włamanie się do bazy danych użytkowników za pomocą listy haseł i skrótów:
Dane z naszej zhakowanej bazy danych:
RawPassword (not stored) | Hashed | Salt
--------------------------------------------------------
letmein WEFLS... WEFOJFOFO...
Wspólny słownik haseł:
Common Password
--------------
letmein
12345
...
Dla każdego rekordu użytkownika zapętl wspólne hasła i zhaszuj je:
for each user in hacked_DB
salt = users_salt
hashed_pw = users_hashed_password
for each common_password
testhash = sha1(common_password + salt)
if testhash = hashed_pw then
//Match! Users password = common_password
//Lets visit the webpage and login now.
end if
next
next
Mam nadzieję, że to lepiej ilustruje mój punkt widzenia.
Biorąc pod uwagę 10 000 typowych haseł i 10 000 rekordów użytkowników, musielibyśmy obliczyć 100 000 000 skrótów, aby wykryć jak najwięcej haseł użytkowników. Może to zająć kilka godzin, ale nie stanowi to problemu.
Aktualizacja dotycząca teorii pękania
Zakładamy, że jesteśmy uszkodzonym hostem internetowym, który ma dostęp do bazy danych zawierającej skróty i sole SHA1 wraz z algorytmem ich łączenia. Baza danych zawiera 10 000 rekordów użytkowników.
Ta witryna twierdzi, że jest w stanie obliczyć 2 300 000 000 skrótów SHA1 na sekundę przy użyciu GPU. (W prawdziwym świecie sytuacja prawdopodobnie będzie wolniejsza, ale na razie użyjemy tej zacytowanej liczby).
(((95 ^ 4) / 2300000000) / 2) * 10000 = 177 sekund
Biorąc pod uwagę pełen zakres 95 drukowalnych znaków ASCII, przy maksymalnej długości 4 znaków podzielonych przez współczynnik obliczeniowy (zmienna) podzielony przez 2 (zakładając, że średni czas na odkrycie hasła będzie wymagał średnio 50% permutacji) dla 10000 użytkownikom wypracowanie wszystkich haseł użytkowników, których długość wynosi <= 4, zajęłoby 177 sekund.
Dostosujmy to trochę, aby uzyskać realizm.
(((36 ^ 7) / 1000000000) / 2) * 10000 = 2 dni
Zakładając, że wielkość liter nie jest uwzględniana, przy długości hasła <= 7 i tylko znakach alfanumerycznych, rozwiązanie dla 10000 rekordów użytkowników zajęłoby 4 dni, a prędkość algorytmu zmniejszyła się o połowę, aby odzwierciedlić narzut i nieidealne okoliczności.
Ważne jest, aby zdać sobie sprawę, że jest to liniowy atak siłowy, wszystkie obliczenia są od siebie niezależne, dlatego jest to idealne zadanie do rozwiązania dla wielu systemów. (IE łatwe do skonfigurowania 2 komputery przeprowadzające ataki z różnych stron, które zajęłyby połowę czasu egzekucji).
Biorąc pod uwagę przypadek rekursywnego haszowania hasła 1000 razy, aby to zadanie było bardziej kosztowne obliczeniowo:
(((36 ^ 7) / 1 000 000 000) / 2) * 1000 sekund = 10,8839117 godzin
Odpowiada to maksymalnej długości 7 znaków alfanumerycznych przy mniej niż połowie szybkości wykonywania z podanej liczby dla jednego użytkownika .
Rekurencyjne mieszanie 1000 razy skutecznie blokuje ogólny atak, ale ataki ukierunkowane na dane użytkownika są nadal podatne na ataki.
źródło
Odpowiedzi:
Tak, potrzebujesz tylko 3 dni na sha1 (sól | hasło). Dlatego dobre algorytmy przechowywania haseł używają mieszania 1000-iteracyjnego: będziesz potrzebować 8 lat.
źródło
Nie powstrzymuje ataków słownikowych.
To, co robi, powstrzymuje kogoś, kto zdoła uzyskać kopię twojego pliku haseł, przed użyciem tęczowej tabeli, aby dowiedzieć się, jakie są hasła z haszów.
Ostatecznie jednak może to być brutalne. Odpowiedzią na tę część jest wymuszenie na użytkownikach, aby nie używali słów ze słownika jako haseł (na przykład minimalne wymagania co najmniej jednej cyfry lub znaku specjalnego).
Aktualizacja :
Powinienem był o tym wspomnieć wcześniej, ale niektóre (większość?) Systemów haseł używają innej soli dla każdego hasła, prawdopodobnie przechowywanej z samym hasłem. To sprawia, że pojedynczy stół tęczowy jest bezużyteczny. W ten sposób działa biblioteka kryptograficzna UNIX , a nowoczesne systemy operacyjne typu UNIX rozszerzyły tę bibliotekę o nowe algorytmy mieszania.
Wiem na pewno, że wsparcie dla SHA-256 i SHA-512 zostało dodane w nowszych wersjach GNU crypt.
źródło
Mówiąc dokładniej, atak słownikowy , tj. Atak, w którym wszystkie słowa z wyczerpującej listy są wypróbowane, nie jest „niemożliwy”, ale staje się niepraktyczny : każdy bit soli podwaja ilość wymaganej pamięci i obliczeń .
Różni się to od wstępnie obliczonych ataków słownikowych, takich jak ataki z użyciem tęczowych tablic, w których nie ma znaczenia, czy sól jest tajna, czy nie.
Przykład: w przypadku 64-bitowej wersji Salt (tj. 8 bajtów) musisz sprawdzić 2 64 dodatkowe kombinacje haseł w swoim ataku słownikowym. Ze słownikiem zawierającym 200 000 słów będziesz musiał stworzyć
testy w najgorszym przypadku - zamiast 200 000 testów bez soli.
Dodatkową zaletą korzystania z soli jest to, że osoba atakująca nie może wstępnie obliczyć skrótów haseł ze swojego słownika. Zajmie to po prostu zbyt dużo czasu i / lub miejsca.
Aktualizacja
Twoja aktualizacja zakłada, że atakujący już zna sól (lub ją ukradł). To oczywiście inna sytuacja. Nadal nie jest możliwe, aby atakujący użył wstępnie obliczonej tabeli tęczy. Duże znaczenie ma tutaj szybkość funkcji haszującej. Aby atak był niepraktyczny, funkcja mieszania musi być powolna. MD5 lub SHA nie są tutaj dobrymi kandydatami, ponieważ zostały zaprojektowane tak, aby były szybkie, lepszymi kandydatami do algorytmów haszujących są Blowfish lub niektóre jego odmiany.
Zaktualizuj 2
Dobra lektura na temat ogólnego zabezpieczania skrótów haseł (wykraczających daleko poza pierwotne pytanie, ale nadal interesująca):
Wniosek z artykułu: Użyj solonych hashów utworzonych za pomocą bcrypt (na podstawie Blowfish) lub Eksblowfish, które pozwalają na użycie konfigurowalnego czasu konfiguracji, aby spowolnić haszowanie.
źródło
Słownik to struktura, w której wartości są indeksowane za pomocą kluczy. W przypadku wstępnie obliczonego ataku słownikowego każdy klucz jest hashem, a odpowiadająca mu wartość to hasło, które skutkuje hashem. Mając wstępnie obliczony słownik w ręku, osoba atakująca może „natychmiast” wyszukać hasło, które wygeneruje skrót niezbędny do zalogowania się.
W przypadku soli przestrzeń wymagana do przechowywania słownika rośnie szybko… tak szybko, że próba wstępnego obliczenia słownika haseł szybko staje się bezcelowa.
Najlepsze sole są wybierane losowo z kryptograficznego generatora liczb losowych. Osiem bajtów to praktyczny rozmiar, a więcej niż 16 bajtów jest bezcelowe.
Sól robi znacznie więcej niż tylko „czyni pracę napastnika bardziej irytującą”. Eliminuje całą klasę ataków - użycie wstępnie obliczonych słowników.
Kolejny element jest niezbędny do całkowitego zabezpieczenia haseł, a jest nim „wzmocnienie klucza”. Jedna runda SHA-1 nie jest wystarczająco dobra: bezpieczny algorytm mieszania haseł powinien działać bardzo wolno obliczeniowo.
Wiele osób używa PBKDF2, funkcji wyprowadzania klucza, która tysiące razy przekazuje wyniki do funkcji skrótu . Algorytm „bcrypt” jest podobny i wykorzystuje powolne iteracyjne wyprowadzanie klucza.
Gdy operacja mieszania jest bardzo powolna, wstępnie obliczona tabela staje się coraz bardziej pożądana dla atakującego. Ale odpowiednia sól pokonuje to podejście.
Komentarze
Poniżej znajdują się komentarze, które złożyłem do pytania.
Bez soli atakujący nie użyłby metody przedstawionej w „Aktualizacji 2”. Po prostu przeszukałby wstępnie obliczoną tabelę i uzyskał hasło w czasie O (1) lub O (log n) (n to liczba możliwych haseł). Sól jest tym, co temu zapobiega i zmusza go do użycia podejścia O (n) pokazanego w „Update 2”.
Po zredukowaniu do ataku O (n), musimy rozważyć, jak długo trwa każda próba. Wzmocnienie klucza może spowodować, że każda próba w pętli zajmie pełną sekundę, co oznacza, że czas potrzebny na przetestowanie 10 000 haseł na 10 000 użytkowników wydłuży się z 3 dni do 3 lat … a przy zaledwie 10 000 haseł prawdopodobnie złamiesz zero hasła w tym czasie.
Musisz wziąć pod uwagę, że atakujący będzie używał najszybszych narzędzi, jakie może, a nie PHP, więc tysiące iteracji zamiast 100 byłyby dobrym parametrem do wzmacniania klucza. Obliczenie skrótu dla pojedynczego hasła powinno zająć dużą część sekundy.
Wzmocnienie klucza jest częścią standardowych algorytmów wyprowadzania kluczy PBKDF1 i PBKDF2 z PKCS # 5, które tworzą świetne algorytmy zaciemniania haseł („kluczem pochodnym” jest „hash”).
Wielu użytkowników StackOverflow odwołuje się do tego artykułu, ponieważ był to odpowiedź na post Jeffa Atwooda o zagrożeniach związanych z tęczowymi stołami. Nie jest to mój ulubiony artykuł, ale bardziej szczegółowo omawia te pojęcia.
Oczywiście zakładasz, że atakujący ma wszystko: sól, hash, nazwę użytkownika. Załóżmy, że osoba atakująca jest skorumpowanym pracownikiem firmy hostingowej, który zrzucił tabelę użytkowników na Twoją stronę fanowską myprettypony.com. Próbuje odzyskać te hasła, ponieważ odwróci się i zobaczy, czy fani twoich kucyków używali tego samego hasła na swoich kontach citibank.com.
Z dobrze zaprojektowanym systemem haseł, będzie to niemożliwe dla tego faceta w celu odzyskania hasła.
źródło
Celem solenia jest zapobieżenie amortyzacji wysiłku napastnika.
Bez soli, pojedyncza tabela wstępnie obliczonych haseł haseł (np. MD5 wszystkich alfanumerycznych 5-znakowych ciągów, łatwych do znalezienia w Internecie) może być używana dla każdego użytkownika w każdej bazie danych na świecie.
Korzystając z soli specyficznej dla witryny, osoba atakująca musi samodzielnie obliczyć tabelę, a następnie może jej użyć na wszystkich użytkownikach witryny.
W przypadku każdego użytkownika osoba atakująca musi poświęcić ten wysiłek oddzielnie na każdego użytkownika.
Oczywiście nie robi to wiele, aby chronić naprawdę słabe hasła prosto ze słownika, ale chroni rozsądnie mocne hasła przed amortyzacją.
źródło
Ponadto - jeszcze jeden ważny punkt - użycie soli specyficznej dla UŻYTKOWNIKA zapobiega wykryciu dwóch użytkowników z TYM SAMYM hasłem - ich skróty byłyby zgodne. Dlatego wiele razy hash to hash (sól + nazwa użytkownika + hasło)
Jeśli spróbujesz zachować hash w tajemnicy, osoba atakująca również nie może zweryfikować skrótów.
Edycja - właśnie zauważyłem, że główny punkt został zawarty w komentarzu powyżej.
źródło
Wprowadzono sole, aby zapobiec atakom tęczowego stołu. Tęczowa tabela to lista wstępnie obliczonych skrótów, co znacznie ułatwia tłumaczenie skrótu na frazę. Musisz zrozumieć, że solenie nie jest skuteczne jako nowoczesna ochrona przed złamaniem hasła, chyba że mamy nowoczesny algorytm haszujący.
Powiedzmy, że pracujemy z SHA1, wykorzystując niedawne exploity odkryte za pomocą tego algo i powiedzmy, że mamy komputer działający z prędkością 1 000 000 hashów na sekundę, znalezienie kolizji zajęłoby 5,3 miliona milionów lat , więc tak, php może pracować 300 na sekundę, duże woop, nie ma znaczenia. Powodem, dla którego solimy, jest to, że jeśli ktoś zadał sobie trud wygenerowania wszystkich popularnych zwrotów słownikowych (2 ^ 160 osób, witamy w exploitach z ery 2007).
Oto rzeczywista baza danych z 2 użytkownikami, których używam do testowania i do celów administracyjnych.
W rzeczywistości schemat solenia to Twój sha1 (czas rejestracji + nazwa użytkownika). Śmiało, powiedz mi moje hasło, to są prawdziwe hasła w produkcji. Możesz nawet usiąść i wymieszać listę słów w php. Zaszaleć.
Nie jestem szalony, po prostu wiem, że to jest bezpieczne. Dla zabawy hasło testu to
test
.sha1(sha1(1281546174.065087 + test) + test) = 5872548f2abfef8cb729cac14bc979462798d023
Musiałbyś wygenerować całą tęczową tabelę
27662aee8eee1cb5ab4917b09bdba31d091ab732
przeznaczoną tylko dla tego użytkownika. Oznacza to, że w rzeczywistości mogę pozwolić, aby moje hasła nie zostały naruszone przez jedną tęczową tabelę, haker musi wygenerować całą tęczową tabelę dla 27662aee8eee1cb5ab4917b09bdba31d091ab732 do testów i ponownie f3f7735311217529f2e020468004a2aa5b3dee7f dla briang Przypomnij sobie 5,3 miliona milionów lat dla wszystkich skrótów. Pomyśl o rozmiarze przechowywania tylko 2 ^ 80 haszów (to dobrze ponad 20 jottabajtów ), to się nie wydarzy.Nie myl solenia ze sposobem tworzenia haszu czegoś, czego nigdy nie możesz zdekodować, jest to środek zapobiegający tłumaczeniu wszystkich haseł użytkowników przez tęczową tabelę . Jest to niemożliwe na tym poziomie technologii.
źródło
Ideą ataku słownikowego jest to, że bierzesz hash i znajdujesz hasło, z którego został obliczony, bez hash obliczania hasha. Teraz zrób to samo z solonym hasłem - nie możesz.
Brak użycia soli sprawia, że wyszukiwanie haseł jest tak proste, jak wyszukiwanie w bazie danych. Dodanie soli sprawia, że atakujący wykonuje obliczenia hash wszystkich możliwych haseł (nawet w przypadku dołączenia słownika znacznie wydłuża to czas ataku).
źródło
Mówiąc najprościej: bez solowania każde hasło kandydata wystarczy tylko raz zaszyfrować, aby sprawdzić je z każdym użytkownikiem, w dowolnym miejscu „znanego wszechświata” (zbiór zainfekowanych baz danych), którego hasło jest zaszyfrowane za pomocą tego samego algorytmu. W przypadku solenia, jeśli liczba możliwych wartości soli znacznie przekracza liczbę użytkowników w „znanym wszechświecie”, każde hasło kandydata musi być zaszyfrowane oddzielnie dla każdego użytkownika, na którym będzie testowane.
źródło
Mówiąc najprościej, solenie nie zapobiega atakowi haszu (bruteforce lub słownikowi), a jedynie utrudnia; atakujący będzie musiał albo znaleźć algorytm solenia (który, jeśli zostanie właściwie zaimplementowany, wykorzysta więcej iteracji), albo zmusić go do brutalnego wykorzystania, co, jeśli nie jest bardzo proste, jest prawie niemożliwe. Solenie prawie całkowicie odrzuca również opcję wyszukiwania tęczowej tabeli ...
źródło
Sól tworzy stół Rainbow ataki znacznie trudniejsze, ponieważ utrudnia złamanie pojedynczego skrótu hasła. Wyobraź sobie, że masz okropne hasło składające się tylko z cyfry 1. Atak tęczowego stołu natychmiast to złamałby.
Teraz wyobraź sobie, że każde hasło w bazie danych jest posypane długą, losową wartością wielu losowych znaków. Teraz twoje kiepskie hasło „1” jest przechowywane w bazie danych jako skrót 1 plus kilka losowych znaków (sól), więc w tym przykładzie tęczowa tablica musi mieć hash dla czegoś takiego: 1.
Zakładając, że twoja sól jest czymś bezpiecznym i losowym, powiedzmy ()% ISLDGHASKLU ( % #% #, tęczowa tablica hakera musiałaby mieć wpis dla 1 * ()% ISLDGHASKLU (*% #% #. Teraz używamy tęczowej tabeli) nawet to proste hasło nie jest już praktyczne.
źródło