Istnieje powszechne nieporozumienie, że hash i szyfrowanie to to samo. Nie są. Hash jest nieodwracalny. Weźmy przykład:
$ echo-n Password123 | md5sum
42f749ade7f9e195bf475f37a44cafcb-
Przekazujemy ciąg "Password123" do algorytmu MD5 (algo), który wykonuje operację matematyczną i zwraca wygenerowany szesnastkowo zakodowany skrót. Jedynym sposobem na uzyskanie tej samej wartości wyjściowej skrótu jest oryginalne wprowadzenie algo. Są konflikty, ale możemy o tym porozmawiać później.
Wyjście większości algorytmów skrótu to szesnastkowo zakodowany ciąg binarny o stałej długości. Inne, takie jak ten przykład, używają ciągów zakodowanych w bazie 64 jako wyjścia. Zwróć uwagę, że długość jest zawsze taka sama:
{SHA} uNF8eZRJ8jmr8WTjyocRJPVpe7w =
{SHA} lqdu/Zr6o2dgIER8Up1/7lcUtgw =
{SHA} qYUOwLMlDEuukA5HCT4LR1kQzco =
{SHA} MXZBCpyWJ7TTs1w2kgGJslwNwTg =
{SHA} 2sAPLaUh9Mz0bI + XxKEg7qyABe8=
TL; Dr
Nie chcę za dużo mówić o szyfrowaniu (bo te rzeczy są dla książek), ale ważne jest, aby umieć odróżnić ciągi hash od ciągów szyfrowanych. Szyfrowanie zwykle wypełnia ciąg znaków, aby spełnić określoną długość przed wystąpieniem szyfrowania. Wymaga również klucza (lub hasła), aby go odszyfrować. Jeśli używasz szyfrowanego hasła, ciąg zmieni się w zależności od długości wprowadzonego danych wejściowych. Jeśli widzisz mnóstwo haseł szyfrowanych o różnej długości, możesz mieć do czynienia z szyfrowaniem zamiast skrótu. AES-256-CBC Przykład szyfrowania ciągów znaków i powiązanego zwykłego tekstu (klucz to "ASDF"):
foobar | U2FsdGVkX19G + KtytNHdj6yH2AVvX26pEmtunS/PRnU = foobarfoobar | U2FsdGVkX18sPpIvN6nVh68lOUCcb3gR2fKbCCnBxog = foobarfoobarfoobar | U2FsdGVkX1/EOnUt57TCW4Rh0EdNnWX + ldatuqv2xexeaeoww0xg/EXJUe9aSUz $ cat szyfrowane_hasła U2FsdGVkX19G + KtytNHdj6yH2AVvX26pEmtunS/PRnU = U2FsdGVkX18sPpIvN6nVh68lOUCcb3gR2fKbCCnBxog = U2FsdGVkX1/EOnUt57TCW4Rh0EdNnWX + ldatuqv2xexeaeoww0xg/EXJUe9aSUz $ dla i w `cat encrypted_passwords`; do echo $i | openssl enc -base64 -d -aes-256-cbc -pass pass:asdf; echo; Gotowe foobar foobarfoobar foobarfoobarfoobar
Teraz możesz pomyśleć: możesz mieć rację. Jednak to, że kluczowe materiały muszą być dostępne dla systemu, oznacza, że w istocie jest to hasło główne z zwykłym tekstem, które znajduje się gdzieś – czy to jako klucz RSA, czy hasło lub hasło w pliku, osadzone w bazie danych, zakodowane na twardo w aplikacji, czy hasło gdzieś w pamięci. pfft, nikt ' nie będzie używał asdf jako klucza do szyfrowania haseł swoich użytkowników '
Użyj tego samego ciągu dla MD5:
foobar | 3858f62230ac3c915f300c664312c63f foobarfoobar | 59faa421729e846dd800dce59943bfc0 foobarfoobarfoobar | 1352aadab322d1a033c27964be0965db
Hasło haszowe jest dalekie od doskonałości, w rzeczywistości jest trochę złe, ale jest gorsze niż szyfrowanie z powodu tego, co próbuje osiągnąć. Użytkownicy częściej wybierają bezwzględne minimalne wymagania niż not i mogą z nich korzystać w wielu witrynach. Wiele „haków "to w rzeczywistości po prostu ataki na ponowne wykorzystanie poświadczeń. Jeśli początkowym kompromisem jest użycie szyfrowania, jedynym wysiłkiem, jaki atakujący musi podjąć, jest znalezienie klucza do odszyfrowania wszystkich haseł. W przypadku haszów muszą przynajmniej włożyć wysiłek, aby je złamać. W przypadku stosowania z nowoczesnymi algorytmami, takimi jak sha512crypt, bcrypt, scrypt czy argon2, złamanie wartości skrótu może wymagać dużego wysiłku.
Dodanie soli to dodanie ciągu do hasła przed haszem. Sól każdego skrótu powinna być unikalna i zwykle wybierana losowo, ponieważ chodzi o to, aby ta sama wartość skrótu „hasło” w zwykłym tekście miała za każdym razem inną wartość. To utrudnia życie kryptosłamaczom, bo żeby sprawdzić słowo "hasło" dla każdego z 1000 użytkowników, każdy z nich ma unikalną SOLĘ, muszą to robić 1000 razy-raz na użytkownika/SOLĘ. Oznacza to również, że nie mogą efektywnie korzystać z wstępnie skompilowanych słowników ani tabel tęczowych (zwykle...), ponieważ wymagają niestandardowej tabeli każdej soli.
Strony czasami to psują i używają uniwersalnej soli dla wszystkich użytkowników; To jest sprzeczne z celem.
Oto skrót SHA1 z dodatkiem soli:
b353977827f67a4ae0318f3a9447fae1c13d9d90:b8d18ca |___________________________________________| hash | sól | separator
Tekst zwykły tego skrótu to „hasło ". Jego wartość soli to „b8d18ca” i używa interfejsu API SHA1 ($salt.$pass). Oznacza to, że algorytm pobierze zwykły tekst hasła, generuje sól i dodaje go przed zwykłym tekstem. Gdy witryna lub aplikacja spróbuje zweryfikować Twoje hasło w przyszłości, przyjmie hasło w zwykłym tekście jako dane wejściowe, odczyta wartość salt w przechowywanym skrócie, dodaje ją przed wybranym hasłem i porównuje wygenerowaną wartość skrótu z przechowywaną wartością skrótu. Cracking Jeśli nie wiesz, że jego część to sól, skrót wygeneruje następujący zwykły tekst:
b8d18capassword
Ponieważ algorytm wprowadza zwykły tekst, sól i wygenerowane wartości skrótu mogą pozostać przejrzyste dla użytkownika. Podczas krakowania, jeśli algorytm jest solny, musimy znać sól, abyśmy mogli go udostępnić podczas generowania kandydata na zwykły tekst. Jeśli zostanie właściwie wykonana, solenie może sprawić, że pękanie będzie bardziej czasochłonne. Używając losowej soli, zmuszasz Crackera do tracenia czasu na próby złamania wartości skrótu, które nie pasują do soli. To z grubsza wypełnia wysiłek wymagany do device_speed/number_of_salts, ponieważ musimy wygenerować kandydata dla każdej soli. Jeśli sól jest statyczna, to operacja matematyczna jest taka sama... prędkość_urządzenia/1. Inny sposób wyświetlenia tego:
nasz GTX 980 cracks SHA1 ($salt.$pass) przy 3576,8 MH/s lub 3,5 miliarda kandydatów na sekundę Nasza hashlista zawiera 1000 unikalnych soli 3 500 000 000 / 1000 = 3 500 000 kandydatów na sekundę
To jest o trzy rzędy wielkości wolniejsze, stratą 99,9%. przy użyciu soli statycznej wygląda to tak:
nasz GTX 980 cracks SHA1 ($salt.$pass) przy 3576,8 MH/s lub 3,5 miliarda kandydatów na sekundę Nasza hashlista zawiera 1 unikalne sól 3 500 000 000 / 1 = 3 500 000 000 Kandydaci na sekundę
Jeśli to nie ma sensu, czytaj dalej, będziemy mieć ładny wykres później...
Inną powszechną ulepszeniem w porównaniu z prostym „hash this plaintext "jest to, że „hash this plaintext, następnie hash ten wynik, a następnie hash ten wynik" powtarza się tysiące razy. Dzięki temu program do łamania haseł musi wykonać tysiące operacji podczas próby pojedynczego hasła kandydata. Nazywa się to iteracją, pętlą lub kosztem zmiennym. Niektóre algorytmy haszowania haseł wykorzystują twardo zakodowane rundy iteracji; Inne Git. Następnie uczyń go konfigurowalnym w części samego skrótu. Na przykład md5crypt () używa MD5, w tym soli, i pętli dokładnie 1000 razy. sha512crypt () używa sha512, zawiera sól i cyrkuje konfigurowalną liczbę razy (domyślnie 5000).
Iteracje wpływają głównie na koszt cyklu obliczeniowego algorytmu skrótu, a nie na jego wykorzystanie pamięci lub inne czynniki. Są to również ważne ataki, gdy projektowanie jest zoptymalizowane do odporności na niektóre typy skrótów, ale jest to zbyt chwastowe, aby o tym tutaj mówić.
Przyjrzyjmy się kilku przykładom, aby zademonstrować wpływ wyboru algorytmu skrótu, niezależnie od tego, czy jest to salted, używanie wielu iteracji itp. Załóżmy, że atakujący zebrał skróty 1000 użytkowników z jakiejś zainfekowanej strony internetowej i chciał tylko przeprowadzić prosty atak, przetestując skróty każdego hasła-143 mln kandydatów na hasła.
Typ skrótu używany przez zainfekowaną stronę internetową będzie miał ogromny wpływ na czas potrzebny atakującemu przejść przez atak. Oto wykres (względny, przybliżony) ile sekund zajmuje wykonanie tego ataku, w zależności od rodzaju używanego skrótu, gdzie standardowa karta graficzna:
No to bezużyteczne! Najsilniejszy typ skrótu jest znacznie wolniejszy, ale szybszy typ jest po prostu spłaszczony do niczego. Spróbujmy ponownie tej samej skali danych, używając logarytmicznego czasu osi X. Gdy paski przesuwają się od lewej do prawej, zwiększają się o potęgę 10:
Więc kilka kluczowych punktów jest następujących: łatwiej jest złamać jakieś hasze hasła w jednej rundzie niż w wielu rundach i bez soli niż z solą. Natomiast gdy niektóre firmy lub strony internetowe ogłaszają naruszenie danych zawierających dane użytkowników, a) najlepiej jest, aby hasło zostało skrótowane, a nie tylko zwykły tekst; b) najlepiej są one solone, a nie tylko haszowane; c) Lepiej, żeby cały czas używali potężnych wielorundowych solonych haszów, a nie tylko pojedynczych.
Zanim spróbuje złamać dany skrót hasła, zależy od krekera, który algorytm skrótu jest używany do jego wdrożenia. Identyfikacja typów skrótów jest zwykle prosta, ale nie zawsze. Crackerzy często dokonują świadomych przypuszczeń na podstawie wskazówek, takich jak długość i format skrótu. W ostatecznym rozrachunku jedynym sposobem na pewność, że zgadywanie typu skrótu jest prawidłowe, jest to, czy skrót został złamany.
Kilka doskonałych zasobów do tego zadania jest dostępnych tutaj i tutaj, a wszystkie pokazują, jak wyglądają typowe wartości skrótu.
Pakiet "hash-identifier" (dostępny tutaj) jest dostępny w Kali Linux, który pomaga w identyfikacji nieznanych typów skrótów.
Kolizja następuje, gdy dwa różne wejścia powodują to samo wyjście skrótu. To jest źle (najwyraźniej). W przypadku haseł może to oznaczać, że nie złamałem twojego faktycznego hasła, ale ponieważ znalazłem dane wejściowe, które generują tę samą wartość skrótu, mogę użyć wartości zwykłego tekstu, aby oszukać system, aby pomyślał, że hasło jest legalne.
Microsoft Office wykorzystuje algorytm, który od lat był podatny na konflikty w ochronie dokumentów. Nie jest rzadkością wykrywanie wielu konfliktów pojedynczego skrótu, a wszystkie te konflikty odblokują dokument. Gdy tylko wykryje się konflikt, algorytm jest praktycznie uszkodzony. Jeśli zdarzy się to raz, to statystycznie rzecz biorąc, jest bardzo prawdopodobne, że powtórzy się. Jedyne, co nas przeszkadza, to czas i moc przetwarzania. W miarę jak algorytmy stają się bardziej solidne, generowanie algorytmów kandydujących i porównywanie danych wyjściowych skrótu w celu ich wyszukiwania wymaga większej mocy i czasu. W rezultacie projektanci stają się coraz lepsi w tworzeniu algorytmów, które są mniej podatne na konflikty.