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.