Różnica między haszowaniem hasła a szyfrowaniem go

140

Obecnie najwięcej głosów na to pytanie brzmi:

Kolejna, która nie jest tak bardzo kwestią bezpieczeństwa, chociaż jest związana z bezpieczeństwem, jest kompletna i skrajna porażka zrozumieć różnicę między haszowaniem hasła a jego szyfrowaniem . Najczęściej spotykane w kodzie, w którym programista próbuje udostępnić niebezpieczną funkcję „Przypomnij mi moje hasło”.

Na czym dokładnie polega ta różnica? Zawsze miałem wrażenie, że haszowanie jest formą szyfrowania. Do jakiej niebezpiecznej funkcji odnosi się plakat?

Claudiu
źródło
Dobrze napisany artykuł o tym, dlaczego nie powinieneś po prostu haszować swoich sekretów / haseł. Zamiast tego użyj HMAC. benlog.com/articles/2008/06/19/dont-hash-secrets
Jay Kumar,
Doskonałe podsumowanie tematu na blogu bezpieczeństwa StackExchange: security.blogoverflow.com/2011/11/…
David J. Liszewski
@JayKumar: Podlinkowany artykuł jest bardzo mylący. Łączy sole haseł (które powinny być widoczne dla atakujących) z kluczami MAC (które mają pozostać tajne). Link Davida J. Liszewskiego dostarcza dużo dokładniejszego opisu.
Rufflewind

Odpowiedzi:

222

Haszowanie to funkcja jednokierunkowa (cóż, mapowanie). Jest to nieodwracalne, stosujesz bezpieczny algorytm mieszania i nie możesz odzyskać oryginalnego ciągu. Jedyne, co możesz zrobić, to wygenerować coś, co nazywa się „kolizją”, czyli znaleźć inny ciąg, który zawiera ten sam hash. Bezpieczne kryptograficznie algorytmy wyznaczania wartości skrótu mają zapobiegać występowaniu kolizji. Możesz zaatakować bezpieczny haszysz za pomocą tęczowego stołu , któremu możesz przeciwdziałać, dodając sól do haszyszu przed jego przechowywaniem.

Szyfrowanie to właściwa (dwukierunkowa) funkcja. Jest odwracalny, możesz odszyfrować zniekształcony ciąg, aby uzyskać oryginalny ciąg, jeśli masz klucz.

Niebezpieczna funkcja, do której się odnosi, polega na tym, że jeśli zaszyfrujesz hasła, Twoja aplikacja ma gdzieś przechowywany klucz, a osoba atakująca, która uzyska dostęp do Twojej bazy danych (i / lub kodu), może uzyskać oryginalne hasła, uzyskując zarówno klucz, jak i zaszyfrowany tekst , podczas gdy z hashem jest to niemożliwe.

Ludzie zwykle mówią, że jeśli cracker jest właścicielem Twojej bazy danych lub Twojego kodu, nie potrzebuje hasła, więc różnica jest dyskusyjna. Jest to naiwne, ponieważ nadal masz obowiązek chronić hasła użytkowników, głównie dlatego, że większość z nich używa w kółko tego samego hasła, narażając ich na większe ryzyko, ujawniając ich hasła.

Vinko Vrsalovic
źródło
1
Aby było jasne, uzyskaj pożądane bezpieczeństwo za pomocą skrótu, musi to być kryptograficznie bezpieczny algorytm skrótu z określoną właściwością, że hash nie tylko jest nieodwracalny, ALE TAKŻE obliczeniowo niepraktyczne do wygenerowania JAKIEKOLWIEK innego ciągu, który generuje ten sam skrót.
Tall Jeff
11
Tak i nie ... Generowanie kolizji skrótów musi być trudne ze względu na bezpieczeństwo Twojej aplikacji, ale nieodwracalność jest wystarczająca, aby uniknąć wycieku hasła.
Dave Sherohman
5
jedwabisty: a jak dokładnie zamierzasz odzyskać oryginalne hasło ze swojej kiepskiej funkcji skrótu? Proponuję ponownie przeczytać komentarz Dave'a
Vinko Vrsalovic,
1
Jeśli już, funkcja skrótu, która ma dużą liczbę kolizji, jest lepsza dla bezpieczeństwa haseł, jednak oznaczałoby to oczywiście, że do zalogowania się na konto można użyć większej liczby haseł.
williamvicary
1
@ n00b soli nie można zakodować na stałe, ponieważ każdy zaszyfrowany element powinien używać osobnej soli. Problem polega na tym, że jeśli zarówno Użytkownik A, jak i Użytkownik B używają hasła „1234”, jeśli znajdziesz hasło Użytkownika A, nie możesz powiedzieć, że Użytkownik B użył tego samego hasła, ponieważ miał różne sole. Nie jest krytyczne dla bezpieczeństwa, że ​​sole są utrzymywane w tajemnicy, większość implementacji po prostu łączy sól z przodu lub z tyłu binarnego obiektu blob, który reprezentuje skrót.
Scott Chamberlain
34

Haszowanie jest funkcją jednokierunkową, co oznacza, że ​​po zaszyfrowaniu hasła bardzo trudno jest odzyskać oryginalne hasło z skrótu. Szyfrowanie to funkcja dwukierunkowa, w której znacznie łatwiej jest odzyskać oryginalny tekst z zaszyfrowanego tekstu.

Zwykłe haszowanie można łatwo pokonać za pomocą ataku słownikowego, w którym atakujący po prostu wstępnie haszuje każde słowo w słowniku (lub każdą kombinację znaków do określonej długości), a następnie używa tego nowego słownika do wyszukiwania zaszyfrowanych haseł. Użycie unikalnej, losowej soli dla każdego zapisanego zaszyfrowanego hasła znacznie utrudnia atakującemu użycie tej metody. Zasadniczo musieliby stworzyć nowy unikalny słownik dla każdej wartości soli, której używasz, strasznie spowalniając ich atak.

Przechowywanie haseł za pomocą algorytmu szyfrowania jest niebezpieczne, ponieważ jeśli użytkownikowi lub administratorowi łatwiej jest odzyskać oryginalne hasło z zaszyfrowanego tekstu, atakującemu łatwiej jest to zrobić.

Bill the Lizard
źródło
12

Hasła zaszyfrowane a haszowane

Jak pokazano na powyższym obrazku, jeśli hasło jest zaszyfrowane, zawsze jest to ukryty sekret, z którego ktoś może wyodrębnić hasło w postaci zwykłego tekstu. Jednak gdy hasło jest zaszyfrowane, jesteś zrelaksowany, ponieważ nie ma prawie żadnej metody odzyskania hasła z wartości skrótu.


Wyodrębnione z zaszyfrowanych i zahaszowanych haseł - co jest lepsze?

Czy szyfrowanie jest dobre?

Hasła w postaci zwykłego tekstu mogą być szyfrowane przy użyciu algorytmów szyfrowania symetrycznego, takich jak DES, AES lub za pomocą innych algorytmów, i mogą być przechowywane w bazie danych. Przy uwierzytelnianiu (potwierdzeniu tożsamości za pomocą nazwy użytkownika i hasła) aplikacja odszyfruje zaszyfrowane hasło przechowywane w bazie danych i porówna je z podanym przez użytkownika hasłem dla równości. W tego typu podejściu do obsługi haseł, nawet jeśli ktoś uzyska dostęp do tabel bazy danych, hasła nie będą po prostu ponownie używane. Jednak jest też zła wiadomość. Jeśli w jakiś sposób ktoś zdobędzie algorytm kryptograficzny wraz z kluczem używanym przez Twoją aplikację, będzie mógł przeglądać wszystkie hasła użytkowników przechowywane w Twojej bazie danych przez odszyfrowanie. „To najlepsza opcja, jaką mam”, może krzyczeć programista, ale czy jest lepszy sposób?

Kryptograficzna funkcja skrótu (tylko w jedną stronę)

Tak, być może przegapiłeś punkt tutaj. Czy zauważyłeś, że nie ma potrzeby odszyfrowywania i porównywania? Jeśli istnieje jednokierunkowa metoda konwersji, w której hasło można przekonwertować na jakieś przekonwertowane słowo, ale operacja odwrotna (wygenerowanie hasła z przekonwertowanego słowa) jest niemożliwa. Teraz nawet jeśli ktoś uzyska dostęp do bazy danych, nie ma możliwości odtworzenia lub wyodrębnienia haseł za pomocą przekonwertowanych słów. Przy takim podejściu nie będzie prawie wcale, aby niektórzy mogli znać ściśle tajne hasła użytkowników; a to ochroni użytkowników używających tego samego hasła w wielu aplikacjach. Jakie algorytmy można zastosować w tym podejściu?

lkamal
źródło
W porządku, ale kiedy logujesz się do usługi, twoje hasło jest wysyłane w postaci zwykłego tekstu / zaszyfrowane, ponieważ jeśli jest wysyłane jako hash na serwer, który ma być porównany. haker mógłby, gdyby znając hash, po prostu wysłać hash na serwer, aby się zalogować. Dlatego hasła do porównania muszą być przesyłane w postaci zaszyfrowanej na serwer, gdzie są odszyfrowane i zahaszowane. To jest bezpieczne, prawda? O ile hasła nigdy nie są przechowywane w postaci niezaszyfrowanej przez długi czas, a wszystkie wystąpienia zaszyfrowanych / jawnych haseł są usuwane z pamięci, gdy nie są już potrzebne?
AgentM
8

Zawsze myślałem, że szyfrowanie można przekonwertować w obie strony, w taki sposób, że wartość końcowa może przywrócić pierwotną wartość, a dzięki funkcji Hashing nie można przywrócić wyniku końcowego do pierwotnej wartości.

CheGueVerra
źródło
8

Algorytmy haszujące mają zwykle charakter kryptograficzny, ale główna różnica polega na tym, że szyfrowanie jest odwracalne poprzez odszyfrowanie, a haszowanie nie.

Funkcja szyfrowania zwykle pobiera dane wejściowe i generuje zaszyfrowane dane wyjściowe o tym samym lub nieco większym rozmiarze.

Funkcja mieszająca pobiera dane wejściowe i generuje zwykle mniejszy wynik, zwykle również o stałym rozmiarze.

Chociaż nie jest możliwe pobranie haszowanego wyniku i "dehashowanie" go w celu przywrócenia oryginalnego wejścia, zazwyczaj można brutalnie wymusić drogę do czegoś, co daje ten sam hash.

Innymi słowy, jeśli schemat uwierzytelniania pobiera hasło, haszuje je i porównuje z zaszyfrowaną wersją wymaganego hasła, może nie być wymagane, abyś faktycznie znała oryginalne hasło, tylko jego skrót i możesz użyć brutalnej siły drogę do czegoś, co będzie pasować, nawet jeśli jest to inne hasło.

Funkcje haszujące są zwykle tworzone w celu zminimalizowania ryzyka kolizji i utrudnienia obliczenia czegoś, co da ten sam hash, co coś innego.

Lasse V. Karlsen
źródło
4

Najlepiej byłoby zrobić jedno i drugie.

Najpierw należy zaszyfrować hasło w celu zapewnienia jednokierunkowego zabezpieczenia. Użyj soli dla dodatkowego bezpieczeństwa.

Następnie zaszyfruj hash, aby chronić się przed atakami słownikowymi, jeśli twoja baza danych skrótów haseł zostanie naruszona.

LogicMagic
źródło
3
Zaszyfruj to czym? Gdyby oszukali Cię tak mocno, że dostali się do bazy danych ze wszystkimi hasłami użytkownika (zaszyfrowanymi, zaszyfrowanymi lub w inny sposób), czy nie byliby w stanie znaleźć klucza do ich odszyfrowania?
Luc
5
Nie należy tego odrzucać. Jest to możliwość, której nie należy wykluczać, że bezpieczeństwo bazy danych zostanie naruszone, a aplikacja nie. Dlatego szyfrowanie skrótu jest dodatkową warstwą bezpieczeństwa.
Arie
@Luc Nie zgadzam się z tobą, moje poprzednie ja. Widziałem zbyt wiele wstrzyknięć SQL, które nie zagroziły kodowi aplikacji (lub plikom konfiguracyjnym) i teraz uważam, że dodanie sekretu jest pomocne, czy to w postaci szyfrowania, czy w postaci pieprzu, ale nie może zastępować mieszania. Pełniejszą odpowiedź można znaleźć tutaj: security.stackexchange.com/a/31846/10863
Luc
3

Haszowanie :

Jest to algorytm jednokierunkowy i raz zaszyfrowany nie może zostać wycofany i to jest jego słodki punkt przeciwko szyfrowaniu.

Szyfrowanie

Jeśli wykonamy szyfrowanie, będzie do tego klucz. Jeśli ten klucz zostanie ujawniony, wszystkie Twoje hasła mogą zostać łatwo odszyfrowane.

Z drugiej strony, nawet jeśli twoja baza danych zostanie zhakowana lub administrator twojego serwera wziął dane z DB i użyłeś zaszyfrowanych haseł, haker nie będzie w stanie złamać tych zaszyfrowanych haseł. Byłoby to praktycznie niemożliwe, gdybyśmy użyli hashowania z odpowiednią solą i dodatkowym zabezpieczeniem z PBKDF2.

Jeśli chcesz przyjrzeć się, jak należy pisać funkcje skrótu, możesz odwiedzić tutaj .

Istnieje wiele algorytmów do wykonywania haszowania.

  1. MD5 - używa funkcji skrótu Message Digest Algorithm 5 (MD5). Wyjściowy hash ma długość 128 bitów. Algorytm MD5 został zaprojektowany przez Rona Rivesta na początku lat 90. i obecnie nie jest preferowaną opcją.

  2. SHA1 - Używa algorytmu skrótu bezpieczeństwa (SHA1) opublikowanego w 1995 roku. Wyjściowy skrót ma długość 160 bitów. Chociaż jest to najczęściej używane, obecnie nie jest to preferowana opcja.

  3. HMACSHA256 , HMACSHA384 , HMACSHA512 - Użyj funkcji SHA-256, SHA-384 i SHA-512 z rodziny SHA-2. SHA-2 został opublikowany w 2001 roku. Wyjściowe długości skrótu wynoszą odpowiednio 256, 384 i 512 bitów, jak wskazują nazwy funkcji skrótu.

Rahul Garg
źródło
1

Chociaż inne odpowiedzi mogą być poprawne, w kontekście, w jakim znajdował się cytat, haszowanie jest narzędziem, które można wykorzystać do zabezpieczania informacji, szyfrowanie jest procesem, który pobiera informacje i bardzo utrudnia odczyt / użycie osobom nieupoważnionym.

Peter Coulton
źródło
-9

Oto jeden z powodów, dla których możesz chcieć użyć jednego nad drugim - odzyskiwanie hasła.

Jeśli przechowujesz tylko skrót hasła użytkownika, nie możesz zaoferować funkcji „zapomnianego hasła”.

Philtron
źródło
16
Najwyraźniej nie przeczytałeś wystarczająco dobrze zaakceptowanej odpowiedzi. Czytaj uważnie: Ty nie powinien oferować hasło pobierania funkcję. Teraz miał do zaoferowania hasło resetowania funkcji. Od lat zarządzam wieloma stronami internetowymi, w tym vBulletin, phpBB, e107, IPB, blogspot, a nawet własnym CMS-em. Jako administrator NIGDY nie musisz mieć czyjegoś wstępnie zaszyfrowanego hasła. Po prostu tego nie robisz. I ty też nie powinieneś tego mieć. Jeśli nie zgadzasz się z tym, co mówię, zapewniam cię: mylisz się.
Lakey
3
Przepraszam, że byłem DUŻO zbyt zły. Po prostu widzę, że zbyt wiele witryn internetowych przechowuje hasła w postaci zwykłego tekstu i frustruje mnie to. Na marginesie: niektóre strony internetowe nastawione na bezpieczeństwo lubią zmuszać użytkowników do okresowej zmiany haseł. Chcą mieć pewność, że dana osoba nie zmieni swojego hasła z „Hasło1” na „Hasło2”. Dlatego zachowują hasło w postaci zwykłego tekstu, aby móc przeprowadzić te porównania w późniejszym terminie. To nie jest dobra praktyka. W takim przypadku muszą najpierw przeprowadzić analizę hasła, tworząc kilka podobnych haseł - haszując każde z nich - i przechowując tylko skróty .
Lakey
7
Nie ma problemu, sprawiło, że wróciłem i ponownie przeczytałem pytanie, a także poszukałem dalszych informacji, więc nie wszystko jest stracone :-) Nie jestem pewien, co myślałem, kiedy pisałem tę odpowiedź. okrzyki
Philtron