Przeglądając forum.php.pl często widziałem, jak użytkownicy przechowują hasła w swoich bazach danych. Najczęściej używają funkcji hashujących md5
, sha1
i sha2
. Wszystko wygląda bardzo dobrze, hasła są przechowywanie bezpiecznie. No właśnie… na ile bezpiecznie.
Nie będę tutaj rozwodził się nad zabezpieczeniem baz danych, w których owa baza haseł się znajduje, ale nad samym zahashowanym ciągu. Wszyscy doskonale wiemy, że istnieją bazy md5 (sha1, sha2 również).
Przezorny zawsze ubezpieczony. Wiadomo, że nigdy nic nie wiadomo.
Pokażę, jak dodatkowo zabezpieczyć nasze hasła. Będą przechowywane w tej samej bazie danych, używając tych samych metod hashowania, a jednak szansa na „złamanie” hasła (wyszukania w bazie) będzie niemożliwa. Posłużymy się ciągiem znaków zwanym przez programistów solą (salt). Przykład implementacji możemy znaleźć w forum IPB, natomiast phpBB pozbawione jest tego fjuczuru ficzera. Cała sprawa sprowadza się do wygenerowania dowolnego kawałka ciągu znaków i doklejenia go do hasła. Sól potrzebna nam będzie również przy porównaniu hasła, więc trzeba ją zapisać w bazie danych obok hasła.
Poniżej zamieszczam przykładową klasę, która obsługuje solenie haseł. Doklejanie soli może być napisane w dowolny sposób, zależy to od Waszej wyobraźni. Ja dodatkowo dodałem element „losowy” w postaci doklejenia do soli wyniku działania funkcji microtime().
- Klasa, która soli hasła.
- Przykład – zapisywanie hasła do bazy danych oraz sprawdzanie go przy logowaniu.
Nie bardzo rozumiem sens solenia. Przed bruteforcem nie chroni, a jak juz ktos sie dostanie do bazy to ma rownie łatwy dostęp do hasha hasła jak i do soli. Rozumiem ze zabezpieczeniem jest tu algorytm solenia. Tzn tego jak owa sol jest „wciskana” w haslo. No ale jakie to ma znaczenie dla forum typu phpBB, gdzie ów algorytm jest dostepny do wgladu dla kazdego?
Spodziewałem się takiego pytania. Istnieją bazy md5, o których pisałem już wcześniej. Możesz zgłębić ten temat szukając ich w google. Nawet, jeżeli system soli jest dostępny jako opensource, to żadna baza haszów nie zidentyfikuje hasła i nie „odwróci” jeżeli taki rekord by w niej istniał. Moja metoda z zastosowaniem microtime() jest zupełnie bezpieczna, bo wprowadza „losowy modyfikator” soli. Natomiast przy stałej soli (np solą jest wycięcie 1 liter hasła) jest już niebezpieczny, dlatego ludzie by to wykorzystali i stworzyliby nowe bazy md5 specjalnie pod ten algorytm. Stosując microtime(), rand() lub dane niezależna od hasła (choćby nazwę użytkownika, która jest niejako modyfikatorem soli) jesteś bezpieczny.
Jeżeli sól jest losowa to jak przy dopasowaniu hasła (przy logowaniu np) odtworzyć tą „sól”?
Napisałem w poście… czytaj uważnie.
Odnośnie klasy… Po co to wszystko? Przecież łatwiej:
< ?php $salt = md5(time()); $pass = md5($pass.$salt); ?>
Nie widzę zwiększonego bezpieczeństwa przy podwójnym haszowaniu.
A, i nie “fjuczuru” tylko “ficzera”.
fjuczur – future – przyszłość
ficzer – feature – dodatek
😉
To wszystko jest bez sensu! Nie widzę większego bezpieczeństwa, a skoro sól zapisujesz w bazie.
Nie lepiej po prostu
sha1(md5($haslo))
red_ag: Podwojne haszowanie. Czy to ma sens? Nawet jesli dwa algorytmy. Potencjalnie latwo sprawdzic, czy przypadkiem wynik bruteforce na sha1 nie zwroci nam md5.
Ile osob tyle pomyslow, wiadomo. Kazdy moze wymyslec inny sposob. Korzystanie z soli, bez wzgledu na algorytm haszowania jest na pewno bardziej bezpieczne niz kilkukrotne haszowanie, bo przeciez mozna:
sha1(md5(sha1(md5(sha1('hah')))))
@marcin, hasło też zapisujesz w bazie. Sól musi być zapisania, jeżeli zdobędziesz moją sól i posolone hasło w md5 to nie jestem taki pewien, czy skorzystasz z bazy md5.
@red_ag, nie podważam, że nie lepiej 🙂 i napisałem o tym w notce. Przedstawiłem problematykę soli i jak się jej używa, bo wiele osób pytało. To, czy lepiej czy nie – to już inna kwestia. Tak naprawdę, to dobrym zabezpieczeniem jest nawet poprzestawianie haszu md5 za pomocą strrev. Zwróciłem tylko uwagę na możliwość solenie hasła.
Na początku myślałem że to zupełnie niepotrzebny wpis, przecież pewne sprawy są oczywiste. Jednak po komentarzach widzę, że jest z tym krucho, bardzo krucho.
Sama klasa wg. mnie jest zupełnie zbyteczna (pisanie klasy dla 3 linijek kodu, które i tak prawdopodobnie wykorzystujemy w 1 miejscu zdecydowanie mija się z celem), lepszy byłby prosty przykład kodu.
„To wszystko jest bez sensu! Nie widzę większego bezpieczeństwa, a skoro sól zapisujesz w bazie.”
No i? Jeśli nie masz kodu, nic Ci to nie da. Przecież sól można zrobić ze wszystkiego, co w niej jest.
Eeee… a o phpowej funkcji crypt() ktoś słyszał?
Pozdrawiam
Sól to „oczywista oczywistość” 😉
O crypt nie słyszałem, ale w zamian mogę hash() podrzucić. Nie samym MD5 czy SHA1 człowiek żyje. Tyle że trzeba mieć na serwerze PHP 5.1.2 albo instalować z PECLa.
Oj,oj. Słabo z teorią u szanownych wypowiadających się. Sól powoduje praktyczne wydłużenie hasła o tyle bajtów ile dodamy soli. Każdy losowo wybrany bajt zwiększa liczbę możliwych kombinacji 256 razy. To powoduje, że tablice tęczowe służące do łamania solonych haseł muszą być znacznie większe niż dla niesolonych, co powoduje małą użyteczność metody tablic tęczowych w przypadku łamania słonych haseł.
Hasła soli większość systemów operacyjnych (m.in. systemy uniksopodobne takie jak MacOS X, Solaris czy Linux). Jedynym popularnym systemem operacyjnym nie stosującym soli do zabezpieczenia haseł systemowych jest MS-Windows (a szkoda 😉 ).
Chyba mało kto uważał na wykładach z kryptografii. Piotr, wielkie dzięki za pożyteczne informacje. Sól po prostu utrudnia „odgadnięcie” hasła na podstawie hashu przechowywanego w bazie danych naszej strony. Pomaga szczególnie tym użytkownikom, którzy stosują krótkie hasła i hasła słownikowe, aby admin serwisu – korzystający z istniejących baz haseł sh1, md5 itd. – nie dowiedział się jakie mają hasło. Zgadzam się, że losowe przechowywanie soli obok hasła w bazie danych jest bardzo dobrym rozwiązaniem. A dla tych co nie wierzą lub myślą, że są mądrzejsi od Einsteina polecam dokładne zapoznanie się z zagadnieniem.
Ciągle nie rozumiem na czym ma polegać ta genialna idea używania soli. Przecież jeśli już ktoś włamie się do bazy, to ma dostęp i do soli i do 'posolonego’ hasła. Wtedy wystarczy użyć tęczowej tablicy i otrzymujemy ciąg w postaci: sól-md5(hasło-sól). Obcinamy sól z przodu i znowu używamy rainbow table. Wynikiem jest ciąg hasło-sól, który po obcięciu soli daje nam szukane hasło.
Więc gdzie tu chwyt?
Z tym że w tęczowej tablicy z pewnością znajduje się twoje hasło (jeśli jest krótkie), ale na pewno nie znajdziesz tam rekordu hasło sól. Sporządzenie tablicy kolejno wygenerowanych haseł o takiej długości jest fizycznie niemożliwe.
A nie lepiej w bazie trzymać wartości takiej zmiennej?
$salt = 'alamakota’;
$salted_pass = md5($pass.$salt).$salt;
a naszą sól trzymać nie w bazie a w skrypcie phpowym?
Nie, tracisz wiele kombinacji to raz, a dwa łatwiej rozbroić Twój mechanizm. Prześledź tok rozumowania solenia haseł raz jeszcze.
Dyskusja zaczęła się ponad 3 lata temu, ale może jeszcze ktoś przeczyta…
A gdyby tak jako soli używać np wlasnie wyniku z md5(microtime()) i zapisać to w jednym polu razem z hasłem w bazie?
Czyli mamy jakieś hasło (np sha256):
933d2ea959a3b35b4bae6aeca13ed83420ea166b4d70baa6b7b0545b817b5717
do tego losową sól:
465512c2441bcf30b309b4532639c9fd7781af0f
A w bazie zapisujemy to jako:
933d2ea959a3b35b4bae6aeca13ed83420ea166b4d70baa6b7b0545b817b5717465512c2441bcf30b309b4532639c9fd7781af0f
skrypt oczywiście wie ile znaków ma hash, ile sól więc rozdziela to na dwa ciągi i może porównać solone hasło z hashem.
Co sądzicie?
@szaleq
Idea soli jest po to, żeby zabezpieczyć się przed tablicami tęczowymi.
Chodzi o to, że tęczowe tabele to powiedzmy „gotowce” z wyliczonymi już haszami haseł. Haseł – czyli powiedzmy wszystkich kombinacji np 8 znakowego hasła – np ala12345. W tęczowej tablicy będzie hasz „7ba6426d90a62cd25e67340fd7af82e4” – przy założeniu, że tablica jest dla md5.
Czyli jak ktoś ukradnie nam bazę z haszami, które nie są posolone, to odszuka w/w hasz i sprawdzi, że w/w hasz to jest odpowiednik hasła ala12345.
Jeżeli natomiast posolimy hasło, to będziemy mieli jakby inne hasło – ala12345 (tego nikt nie zna)
sol – da8381c790622cf7a4ca3134532f7dd2
nowe hasło: ala12345 + da8381c790622cf7a4ca3134532f7dd2 -> ala12345da8381c790622cf7a4ca3134532f7dd2
Nie ma tablic tęczowych dla haseł tej długości. To jedno. Dwa, nawet gdyby ktoś chciał tą tablicę przygotować, to dla każdego usera usiałoby być od nowa generowana tablica – inna sól.
Sól to podstawa.
*oczekuje nagrody złotej łopaty*
Dodajmy jedno: solenie można dodatkowo zabezpieczać wedle wyobraźni. Np. sól i gotowy hasz są kodowane sha(), „tasujemy” je ze sobą (co drugi do gotowego hasz co drugi znak wpisujemy kolejne znaki z soli). W samym haszu stosujemy kombinację w stylu: pół_soli + hasło + drugie_pół_soli + odbicie_lustrzane_hasła. Teraz hacker ma podwójną zagadkę: gdzie jest sól? [może być przecież hasz+sól, sól+hasz, „przetasowanie” też może być w różnej kolejności], jak w zasadzie posolono hasło? Ile głów tyle pomysłów 😉