2009-08-02 14 views
222

Zawsze użyłem odpowiedniego ciągu soli dla wpisu podczas mieszania haseł do przechowywania bazy danych. Dla moich potrzeb, przechowywanie soli w DB obok zakodowanego hasła zawsze działało dobrze.Gdzie przechowujesz swoje struny solne?

Jednak niektórzy ludzie zalecają przechowywanie soli oddzielnie od bazy danych. Ich argumentem jest to, że jeśli baza danych zostanie naruszona, atakujący może nadal budować tęczowy stół, biorąc pod uwagę konkretny ciąg soli, aby złamać jedno konto naraz. Jeśli to konto ma uprawnienia administratora, może nie musi nawet łamać żadnych innych.

Czy z punktu widzenia bezpieczeństwa warto przechowywać sole w innym miejscu? Rozważmy aplikację internetową z kodem serwera i DB na tym samym komputerze. Jeśli sole są przechowywane w płaskim pliku na tym komputerze, istnieje szansa, że ​​jeśli baza danych zostanie naruszona, plik soli też będzie.

Czy są jakieś zalecane rozwiązania?

+7

Jeśli istnieje miejsce, w którym można przechowywać sól, do której atakujący nie może się dostać, wówczas należy po prostu przechowywać tam również hasła. Ale dlaczego nie użyć innej soli dla każdego hasła? – jrockway

+6

Używa innej soli dla każdego hasła, jrockway. – Amber

+9

Jak duże są twoje sole? Twoje sole powinny być wystarczająco duże (32 bity?), Że praktycznie nie ma szansy, że stół tęczowy został wstępnie obrobiony. –

Odpowiedz

232

Celem tabel tęczowych jest to, że są one tworzone z wyprzedzeniem i rozprowadzane masowo, aby zaoszczędzić czas obliczeń dla innych - tworzenie taktycznych tabel w locie zajmuje tyle samo czasu, co złamanie hasła + soli kombinacja bezpośrednio (ponieważ efektywnie to, co robi się przy generowaniu tablic tęczowych, to przed uruchomieniem obliczeń do brutalnego wymuszania hasha), tym samym argument, że znajomość soli, którą ktoś mógłby "wygenerować tęczowy stół" jest fałszywy.

Nie ma sensu przechowywanie soli w oddzielnym pliku, o ile są one przeznaczone dla poszczególnych użytkowników - celem jest to, aby jeden tęczowy stół nie mógł złamać każdego hasła DB.

+15

Uzgodnione. Model zagrożenia, który chronisz przez przechowywanie soli osobno, to użytkownik, który może w jakiś sposób uzyskać dostęp do soli w DB za pomocą nikczemnych środków, ale nie za wartość skrótu (w DB). I że ta osoba zacznie obliczać tęczowy stół z góry, zakładając, że będzie mógł później znaleźć hasz. Nie niemożliwe, ale też nie warte wysiłku inżynieryjnego do obrony przed tą pojedynczą aleją ataku. –

+0

Ładny post, zastanawiałem się nad tym samym. Nigdy nie myślałem o soli na użytkownika, myślę, że jedna sól będzie działać dla wszystkich użytkowników. A co z solą przechowywaną jako plik XML ładowany przez serwer aplikacji? a może jakoś zakodowane w serwletu? – Jigzat

+8

@Jigzat - Solenie nie ma sensu, jeśli nie masz osobnej soli dla każdego użytkownika. Celem soli jest złamanie hashe oddzielnym zadaniem dla każdego hasła użytkownika; jeśli sól jest taka sama dla wszystkich z nich, to nie jest tak. – Amber

22

Często są one dodawane do skrótu i ​​przechowywane w tym samym polu.

Nie ma potrzeby przechowywania ich osobno - celem jest użycie losowej soli dla każdego hasła, aby pojedynczy tabele tęczowe nie mogły być użyte przeciwko całemu zestawowi skrótów haseł. W przypadku losowych soli napastnik musi brutalnie zmusić każdą mieszankę oddzielnie (lub obliczyć tabelę tęczową dla wszystkich możliwych soli - znacznie więcej pracy).

Jeśli dysponujesz bezpieczniejszym miejscem do przechowywania, warto przechowywać tam hasze.

+3

Ale co się stanie, jeśli wszystkie zaszyfrowane hasła zostaną ujawnione, łącznie z ich solą? Czy to nie jest tak samo niebezpieczne? – mghaoui

+8

@mghaoui Ale jeśli chciałbyś poznać "hasło", nadal musiałbyś stworzyć Tabelę tęczową dla każdej soli, chyba że niektóre sole są takie same. – Franklin

32

Podam nieco inny wniosek w tej sprawie.

Zawsze przechowuję sól wymieszaną z hashem z solonym hasłem.

Na przykład, umieszczę pierwszą połowę soli przed solonym hashem hasła, a ostatnią połowę soli po solonym haszem hasła. Aplikacja jest świadoma tego projektu, więc może pobrać te dane, i uzyskać hash soli i solonego hasła.

Moja Uzasadnieniem takiego podejścia:

Jeśli dane hasło/hash jest zagrożona i wpada w ręce atakującego, atakujący nie będzie wiedział, co sól jest od patrzenia na dane. W ten sposób atakujący nie może praktycznie wykonać brutalnego ataku, aby uzyskać hasło pasujące do hasza, ponieważ nie zna on hasha, od którego zaczyna się i nie ma możliwości dowiedzenia się, które części danych są częściami soli, lub części hasha z hasłem solonym (, chyba że zna logikę uwierzytelniania twojej aplikacji).

Jeśli hash z hasłem solonym jest przechowywane tak jak jest, można wykonać atak brute-force, aby uzyskać hasło, które po zasoleniu i mieszaniu generuje te same dane, co hash z hasłem solonym.

Jednak, na przykład, nawet jeśli asocjacja z hasłem solonym była przechowywana tak jak jest, lecz wstępnie zawierała pojedynczy losowy bajt, o ile atakujący nie jest świadomy, że ten pierwszy bajt ma zostać odrzucony, również zwiększyć trudność ataku. Twoja aplikacja będzie wiedziała, że ​​odrzuca pierwszy bajt danych, gdy jest używany do uwierzytelnienia użytkownika.

Zawarcie tego ..

1) Nie wolno przechowywać dane, że aplikacja używa uwierzytelniania w to dokładna forma.

2) Jeśli to możliwe, utrzymuj logikę uwierzytelniania w tajemnicy, aby zwiększyć bezpieczeństwo.

pójść o krok dalej ..

Jeśli nie można zachować logikę uwierzytelniania tajemnicę swojej aplikacji - wiele osób wie, w jaki sposób dane są przechowywane w bazie danych. I przypuśćmy, że zdecydowałeś się przechowywać mieszany hash z domieszką soli razem z solą, z częścią soli poprzedzającą hash z solonym hasłem i resztą soli, która się do niego dołącza.

Podczas generowania losowej soli, możesz również losowo zdecydować, jaka część twojej soli będzie przechowywana przed/po hashowaniu solonym hasłem.

Na przykład generowana jest losowa sól o wielkości 512 bajtów. Dodajesz sól do swojego hasła i otrzymujesz skrót SHA-512 swojego solonego hasła. Generujesz losową liczbę całkowitą 200. Następnie przechowujesz pierwsze 200 bajtów soli, następnie hash solonego hasła, a następnie resztę soli.

Podczas uwierzytelniania hasła wprowadzanego przez użytkownika, aplikacja przejdzie przez ciąg znaków i przyjmie, że pierwszy 1 bajt danych jest pierwszym 1 bajtem soli, a następnie solonym hashem. Ta przepustka nie powiedzie się. Aplikacja będzie kontynuowana przez użycie pierwszych 2 bajtów danych jako pierwszych 2 bajtów soli i powtórzyć, aż wynik dodatni zostanie znaleziony po użyciu pierwszych 200 bajtów jako pierwszych 200 bajtów soli. Jeśli hasło jest nieprawidłowe, aplikacja będzie nadal próbowała wszystkich permutacji, dopóki nie zostaną znalezione żadne.

Zalety tego rozwiązania:

Zwiększone bezpieczeństwo - nawet jeśli logika uwierzytelniania jest znana dokładna logika nie jest znany w czasie kompilacji. Próba brutalnej siły jest praktycznie niemożliwa, nawet przy znajomości dokładnej logiki. Zwiększona ilość soli zwiększy bezpieczeństwo.

Wady tego podejścia:

Ponieważ dokładna logika jest wywnioskować w czasie wykonywania, takie podejście jest bardzo intensywnie CPU. Im dłuższa długość soli, tym podejście staje się bardziej obciążające procesor.

Uwierzytelnianie nieprawidłowych haseł wiąże się z najwyższymi kosztami procesora. Może to przynieść efekt odwrotny do uzasadnionych żądań, ale zwiększa bezpieczeństwo przed atakującymi.

To podejście może być realizowane na różne sposoby i może być jeszcze bardziej bezpieczne dzięki zastosowaniu soli o zmiennej szerokości i/lub skrótów z hasłami solennymi.

+5

W swoim podejściu dodajesz sekret do procesu haszowania (algorytm, który stosuje sól). Tę tajemnicę można dodać znacznie łatwiej dodając ** pieprz ** dodatkowo do soli, próbowałem wskazać to w moim [tutorialu] (http://www.martinstoeckli.ch/hash/en/index.php) . Nowoczesne funkcje mieszające, takie jak BCrypt, będą stosować sól samodzielnie, używając oryginalnej soli w każdej iteracji, więc i tak nie będziesz mieć nad tym kontroli. – martinstoeckli

+0

@martinstoeckli Jeśli masz rację, że BCrypt sam stosuje sól, to przechowywanie tej soli + hasha zależy od ciebie jako programisty. Więc można łatwo dodać paprykę do soli + hash i utrzymywać ją w bazie danych. Następnie, po kolejnym pobraniu, odczytasz wartość z bazy danych, usuniesz wartość pieprzu i przekazujesz pozostałą wartość do BCrypt. – PeterToTheThird

+1

@PeterToThThird - To neguje przewagę pieprzu. Papryka dodaje tajemnicę po stronie serwera i działa tak długo, jak długo pozostaje tajna (w przeciwieństwie do soli). Typowym atakiem jest iniekcję SQL, gdy ktoś uzyskuje dostęp do bazy danych, ale nie do kodu, pieprz przechowywany w bazie danych będzie bezużyteczny. Większość implementacji BCrypt automatycznie doda sól do wynikowej wartości hash, więc ta wartość zawiera już sól, czynnik kosztu, algorytm i hash. Ten ciąg może być przechowywany w jednym polu o długości 60 znaków. – martinstoeckli

3

oparciu o ASP.NET MVC 4 Developing Web Applications książkę Williama Penberthy:

  1. Uzyskiwanie dostępu do soli przechowywane w oddzielnej bazie danych wymaga hakerom włamać dwa różnych baz danych, aby uzyskać dostęp do soli i solone hasło. Przechowywanie ich w tej samej tabeli co hasło lub nawet innej tabeli z tej samej bazy danych oznaczałoby, że gdy hakerzy uzyskają dostęp do bazy danych, będą mieli dostęp zarówno do soli, jak i hasła hash. Ponieważ bezpieczeństwo obejmuje proces polegający na tym, że włamanie się do systemu jest zbyt kosztowne lub czasochłonne, podwojenie kwoty, jaką musiałby uzyskać haker, spowodowałoby, że system byłby bezpieczniejszy.
  2. Łatwość użycia jest głównym powodem przechowywania soli w tej samej bazie danych, co hashowane . Nie musiałbyś zapewniać, że dwie bazy danych są zawsze dostępne w tym samym czasie i zawsze zsynchronizowane. Zaleta posiadania soli jest minimalna, jeśli każdy użytkownik ma losową sól, ponieważ chociaż może to ułatwić znalezienie hasła danej osoby, ilość siły niezbędnej do złamania haseł całego systemu będzie wysoka. Na tym poziomie dyskusji, tak naprawdę oczekiwane jest: ochrona haseł. Jeśli hakerzy uzyskali kopię bazy danych, dane aplikacji użytkownika są już zagrożone. W tym momencie problemem jest ograniczenie ryzyka użytkowników z powodu potencjału udostępnianych haseł.
  3. Wymóg utrzymania dwóch oddzielnych połączonych baz danych jest obszerny. To prawda, że ​​to dodaje poczucie bezpieczeństwa, ale jedyną korzyścią, jaką daje, jest ochrona hasła, pojedynczego elementu danych. Jeśli każde pole w bazie danych zostało zaszyfrowane pojedynczo, a ta sama sól została użyta do tego celu, byłoby rozsądniej przechowywać je oddzielnie niż dane, ponieważ podstawowe zabezpieczenia systemu zostały ulepszone.