Gdzie przechowujesz swoje struny solne?

250

Zawsze korzystałem z prawidłowego ciągu soli dla każdego wpisu podczas mieszania haseł do przechowywania danych. Na moje potrzeby przechowywanie soli w DB obok zaszyfrowanego hasła zawsze działało dobrze.

Jednak niektóre osoby zalecają przechowywanie soli oddzielnie od bazy danych. Ich argumentem jest to, że jeśli baza danych zostanie przejęta, atakujący może nadal zbudować tęczową tabelę, biorąc pod uwagę konkretny ciąg soli, aby złamać jedno konto na raz. Jeśli to konto ma uprawnienia administratora, być może nie będzie musiał nawet łamać żadnych innych.

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

Czy są jakieś zalecane rozwiązania tego problemu?

Friedo
źródło
9
Jeśli jest miejsce, w którym możesz przechowywać sól, do której atakujący nie może dostać, powinieneś również przechowywać hasła. Ale dlaczego nie użyć innej soli do każdego hasła?
jrockway,
8
Używa innej soli do każdego hasła, jrockway.
Amber
9
Jak duże są twoje sole? Wasze sole powinny być na tyle duże (32 bity?), Że praktycznie nie ma szansy na to, aby tęcza została wcześniej obliczona.
M. Dudley,
@ emddudley W tych czasach miałem zwyczaj używania 64-bitowej liczby całkowitej jako soli, ale nie ma powodu, dla którego nie mogę ich dłużej.
friedo
10
Autor PWDTK tutaj sourceforge.net/projects/pwdtknet , szczerze mówiąc, nie martwiłbym się i po prostu przechowywałbym sól w tym samym DB jako hasło. Zawsze powinieneś założyć, że osoba atakująca zna sól, więc powinieneś skupić się na użyciu DUŻEJ soli CRYPTO-RANDOM i wykonaniu wystarczającego kluczowego rozciągania (iteracje w PBKDF2), tak aby uczynienie nawet jednej tabeli tęczy dla jednej znanej soli było niemożliwe. Szczerze mówiąc, to, co próbujesz osiągnąć, umieszczając sól w innym miejscu, to „Bezpieczeństwo przez Obscurity” i ogólnie nie przynosi żadnych korzyści, gdy spojrzysz na rzeczy, takie jak inny serwer, który potencjalnie może spaść.
thashiznets

Odpowiedzi:

259

Istotą tablic tęczowych jest to, że są one tworzone z wyprzedzeniem i masowo dystrybuowane, aby zaoszczędzić czas na obliczenia dla innych - tak samo długo trwa generowanie tabel tęczowych, jak bezpośrednie złamanie kombinacji hasła i soli (ponieważ tak naprawdę to, co dzieje się podczas generowania tablic tęczy, to wstępne obliczenia dla brutalnego wymuszania skrótu), dlatego argument, że znając sól ktoś może „wygenerować tęczową tabelę”, jest fałszywy.

Nie ma sensu przechowywanie soli w osobnym pliku, o ile dotyczą one poszczególnych użytkowników - celem soli jest po prostu sprawienie, aby jedna tablica tęczy nie mogła złamać każdego hasła w bazie danych.

Bursztyn
źródło
17
Zgoda. Model zagrożenia, przed którym chronisz, przechowując sól osobno, to użytkownik, który w jakiś sposób może uzyskać dostęp do soli w bazie danych za pomocą nikczemnych środków, ale nie hash (w bazie danych). I ta osoba zacznie z wyprzedzeniem obliczać tęczowy stół, zakładając, że będzie mógł później znaleźć skrót. Nie jest to niemożliwe, ale również nie warte wysiłku inżynieryjnego w obronie przed tą pojedynczą aleją ataku.
Tom Ritter,
Niezły post, zastanawiałem się nad tym samym. Nigdy nie myślałem o soli na użytkownika. Myślałem, że jedna sól będzie działać dla wszystkich użytkowników. Co z solą przechowywaną jako plik XML ładowany przez serwer aplikacji? a może jakoś zakodowany w serwlet?
jigzat
9
@Jigzat - Solenie nie ma sensu, jeśli nie masz oddzielnej soli dla każdego użytkownika. Chodzi o to, aby łamanie skrótów było oddzielnym zadaniem dla każdego hasła użytkownika; jeśli sól jest taka sama dla wszystkich, to tak nie jest.
Amber
3
@TomRitter to nie jedyny przypadek. zakładasz, że wszystkie hasła są skomplikowane. niektórzy napastnicy mogą wziąć sól i skrót i sprawdzić tylko 10 000 najczęściej używanych haseł. w ten sposób zdobędą przyzwoitą liczbę ludzi. jeśli jednak nie mają dostępu do soli, to znaczy, że użytkownik ma dłuższe, bezpieczniejsze hasło. teraz, jak prawdopodobne jest, że baza danych soli pozostanie bezpieczna podczas kradzieży bazy danych haseł, jest przedmiotem dyskusji, ale to osobna kwestia.
chacham15
@Amber, uważam, że TomRitter ma rację. Przechowywanie soli osobno oznacza różnicę między zmuszaniem atakującego do użycia ataku brutalnego a łatwiejszym atakiem słownikowym. Jeśli znasz sól, możesz ją po prostu dołączyć podczas ataku słownika młyna. Jeśli potrafisz w 100% bronić swojej soli, możesz po prostu użyć tej samej soli i zmusić atakujących do brutalnego użycia siły (nawet dla użytkowników, którzy używają hasła jako hasła). Ale czy możesz obronić swoją sól… prawdopodobnie nie. Równie dobrze może zmniejszyć punkty awarii, przechowując je obok skrótu i ​​egzekwować silniejsze reguły haseł.
Ultratrunks,
35

Przedstawię nieco inne podejście do tego.

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

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

Moje uzasadnienie tego podejścia:

Jeśli hasło / dane skrótu zostaną naruszone i wpadną w ręce atakującego, atakujący nie będzie wiedział, na czym polega sól, patrząc na dane. W ten sposób atakujący nie może praktycznie wykonać ataku siłowego, aby uzyskać hasło pasujące do skrótu, ponieważ nie zna skrótu na początku i nie ma sposobu, aby wiedzieć, które części danych są częściami soli, lub części skrótu z solonym hasłem ( chyba że zna logikę uwierzytelniania aplikacji) ).

Jeśli skrót hasłem z solonym hasłem jest przechowywany tak, jak jest, to można przeprowadzić atak siłowy, aby uzyskać hasło, które po soleniu i skrócie generuje te same dane, co hash z solonym hasłem.

Jednak na przykład, nawet jeśli skrót hasłem z solonym hasłem był przechowywany w stanie, w jakim się znajduje, ale jest poprzedzony pojedynczym losowym bajtem, o ile osoba atakująca nie wie, że ten pierwszy bajt zostanie odrzucony, zwiększyłoby to również trudność ataku. Twoja aplikacja wiedziałaby, że powinien usunąć pierwszy bajt danych, gdy jest używany do uwierzytelnienia użytkownika.

Wniosek do tego ..

1) Nigdy nie przechowuj danych używanych przez aplikację uwierzytelniającą w jej dokładnej formie.

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

Idź o krok dalej ..

Jeśli nie możesz zachować logiki uwierzytelniania aplikacji w tajemnicy - wiele osób wie, jak Twoje dane są przechowywane w bazie danych. Przypuśćmy, że zdecydowałeś się przechowywać mieszany hasłem z solonym hasłem razem z solą, z częścią soli poprzedzającej skrót z solonym hasłem, a reszta soli go dołącza.

Podczas generowania losowej soli możesz również losowo zdecydować, jaka część soli będzie przechowywana przed / po skrócie solonego hasła.

Na przykład generujesz losową sól 512 bajtów. Dołączasz sól do swojego hasła i uzyskujesz skrót SHA-512 swojego solonego hasła. Generujesz także losową liczbę całkowitą 200. Następnie zapisujesz pierwsze 200 bajtów soli, następnie hash z solonym hasłem, a następnie resztę soli.

Podczas uwierzytelniania hasła użytkownika aplikacja prześle ciąg znaków i przyjmie, że pierwszy 1 bajt danych jest pierwszym 1 bajtem soli, a następnie hash solony. Ta przepustka się nie powiedzie. Aplikacja będzie kontynuowana przy użyciu pierwszych 2 bajtów danych jako pierwszych 2 bajtów soli i będzie powtarzana aż do znalezienia wyniku pozytywnego po użyciu pierwszych 200 bajtów jako pierwszych 200 bajtów soli. Jeśli hasło jest niepoprawne, aplikacja będzie próbowała wszystkich permutacji, dopóki nie zostaną znalezione.

Zalety tego podejścia:

Zwiększone bezpieczeństwo - nawet jeśli znana jest logika uwierzytelniania, dokładna logika jest nieznana w czasie kompilacji. Wykonanie ataku brutalną siłą jest praktycznie niemożliwe, nawet przy znajomości dokładnej logiki. Zwiększone długości soli jeszcze bardziej zwiększą bezpieczeństwo.

Wady tego podejścia:

Ponieważ dokładna logika jest wywnioskowana w czasie wykonywania, takie podejście wymaga bardzo dużo procesora. Im dłuższa długość soli, tym bardziej wymaga to procesora.

Uwierzytelnianie niepoprawnych haseł wiąże się z najwyższym kosztem procesora. Może to przynieść efekt przeciwny do zamierzonego, ale zwiększa bezpieczeństwo przed atakującymi.

To podejście można wdrożyć na różne sposoby i może być jeszcze bardziej bezpieczne przy użyciu soli o zmiennej szerokości i / lub hashów z solonym hasłem.

Ibraheem
źródło
9
Dzięki swojemu podejściu dodajesz tylko sekret do swojego procesu mieszania (algorytm, który stosuje sól). Ten sekret możesz dodać o wiele łatwiej, dodając pieprz dodatkowo do soli, starałem się to podkreślić w moim tutorialu . Nowoczesne funkcje skrótu, takie jak BCrypt, zastosują sól samodzielnie, używając oryginalnej soli w każdej iteracji, więc i tak nie będziesz mieć nad tym kontroli.
martinstoeckli
@martinstoeckli Chociaż masz rację, że BCrypt stosuje sól samodzielnie, przechowywanie tej soli + skrótu zależy od ciebie, jako programisty. Możesz więc łatwo dodać pieprz do skrótu + sól i utrwalić go w bazie danych. Następnie przy kolejnym pobieraniu odczytujesz wartość z bazy danych, usuwasz wartość pieprzową i przekazujesz pozostałą wartość do BCrypt.
PeterToTheThird
2
@PeterToTheThird - To zniweczyłoby przewagę pieprzu. Papryka dodaje tajemnicę po stronie serwera i działa tylko tak długo, jak długo pozostaje tajna (w przeciwieństwie do soli). Typowym atakiem jest wstrzykiwanie SQL, gdy ktoś uzyska dostęp do bazy danych, ale nie do kodu, pieprz przechowywany w bazie danych będzie wtedy bezużyteczny. Większość implementacji BCrypt doda sól automatycznie do wynikowej wartości skrótu, więc ta wartość już zawiera sól, współczynnik kosztów, algorytm i skrót. Ten ciąg może być przechowywany w jednym polu o długości 60 znaków.
martinstoeckli
Aby dodać, używając funkcji „wzmocnienia klucza”, takiej jak BCrypt, nie masz kontroli nad użyciem soli. Jeśli jednak chcesz użyć pieprzu, po prostu dodaj pieprz do soli i użyj go jako „pieprzu” zamiast „soli” wprowadzonej do funkcji mieszającej. „Pieprz” jest zatem odpowiednim fragmentem danych, które nie są przechowywane w bazie danych, ale są osadzone w kodzie uwierzytelniającym lub przechowywane w innej bezpiecznej lokalizacji. Podszedłem do problemu z ogólnej perspektywy, używając SHA-512 jako funkcji przykładowej, ale BCrypt itp. Może być również używany w podobny sposób.
Ibraheem
2
@martinstoeckli - tak, rzeczywista implementacja zależy od używanej funkcji skrótu. Oczywiście przy wdrażaniu logiki uwierzytelniania należy wziąć pod uwagę parametry i wyniki funkcji skrótu. Ostatecznie pieprz to kolejna zmienna wprowadzona do funkcji skrótu , która nie jest przechowywana w tym samym miejscu co sól i skrót.
Ibraheem
23

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

Nie ma potrzeby przechowywania ich osobno - chodzi o użycie losowej soli dla każdego hasła, aby nie można było użyć pojedynczej tęczowej tabeli dla całego zestawu skrótów haseł. W przypadku losowych soli atakujący musi brutalnie wymusić każdy skrót osobno (lub obliczyć tęczową tabelę dla wszystkich możliwych soli - znacznie więcej pracy).

Jeśli miałbyś bezpieczniejsze miejsce do przechowywania, sensowne byłoby po prostu przechowywanie tam skrótów.

nikt
źródło
4
Ale co się stanie, jeśli wszystkie zaszyfrowane hasła zostaną ujawnione, w tym ich pasująca sól? Czy to nie jest tak niepewne?
mghaoui
10
@mghaoui Ale jeśli chcesz poznać „hasło”, nadal musisz zbudować Tęczowy Stół dla każdej soli, chyba że niektóre z nich są takie same.
Franklin,
4

Na podstawie książki Developing ASP.NET MVC 4 autorstwa Williama Penberthy'ego:

  1. Uzyskanie dostępu do soli przechowywanych w oddzielnej bazie danych wymaga od hakerów zhakowania dwóch różnych baz danych w celu uzyskania dostępu do soli i solonego hasła. Przechowywanie ich w tej samej tabeli co hasło lub nawet w innej tabeli tej samej bazy danych oznaczałoby, że gdy hakerzy uzyskają dostęp do bazy danych, będą mieli dostęp zarówno do hasła, jak i hasła. Ponieważ bezpieczeństwo obejmuje proces powodowania, że ​​włamanie do systemu jest zbyt drogie lub czasochłonne, aby było tego warte, podwojenie ilości dostępu, jaki musiałby uzyskać haker, powinno zwiększyć bezpieczeństwo systemu.
  2. Łatwość użycia jest głównym powodem przechowywania soli w tej samej bazie danych, co hashowane hasła. Nie trzeba mieć pewności, że dwie bazy danych są zawsze dostępne jednocześnie i zawsze w synchronizacji. Zaleta posiadania soli jest minimalna, jeśli każdy użytkownik ma losową sól, ponieważ chociaż może to ułatwić odnalezienie hasła danej osoby, siła niezbędna do złamania haseł systemu będzie ogólnie wysoka. Na tym poziomie dyskusji tak naprawdę oczekuje się: ochrony haseł. Jeśli hakerzy uzyskali kopię bazy danych, dane aplikacji są już zagrożone. W tym momencie problemem jest ograniczenie ryzyka użytkowników ze względu na potencjał wspólnych haseł.
  3. Wymóg utrzymywania dwóch oddzielnych połączonych baz danych jest szeroki. To prawda, że ​​dodaje poczucie bezpieczeństwa, ale jedyną korzyścią, jaką daje, jest to, że chroni hasło, pojedynczy element danych. Gdyby każde pole w bazie danych było zaszyfrowane indywidualnie, a do tego użyto tej samej soli, sensowniej byłoby przechowywać je oddzielnie od danych, ponieważ zwiększono podstawowe bezpieczeństwo systemu.
DaNeSh
źródło
Jeśli aplikacja może się jednak uwierzytelnić w obu bazach danych, to czy nie jest to w zasadzie to samo, jakby była jedną bazą danych, jeśli osoba atakująca naruszyła kod aplikacji?
John Ernest,
0

Chodzi o to, aby wszystkie tabele tęczy były bezużyteczne i wymagały wykonania nowego zestawu. Zgadnięcie sznurka zajmuje tyle samo czasu, co zrobienie tęczowego stołu. Na przykład hash SHA-256 „hasła” to 5e88 4898 da28 0471 51d0 e56f 8dc6 2927 7360 3d0d 6aab bdd6 2a11 ef72 1d15 42d8. Po dodaniu soli, takiej jak „badpassword”, nowym ciągiem do zaszyfrowania jest „passwordbadpassword”, które ze względu na efekt lawinowy radykalnie zmienia wyjście, na457b f8b5 37f1 802e f9c8 2e46 b8d3 f8b5 721b 7cbb d485 f0bb e523 bfbe 73e6 58d6 .

Zwykle sól jest po prostu przechowywana w tej samej bazie danych co hasło, również dlatego, że jeśli jedna baza danych zostanie zhakowana, prawdopodobne jest, że druga również.

Eric Jin
źródło