Bezpieczne haszowanie haseł Haszowanie haseł Ta sekcja wyjaśnia powody, dla których należy używać funkcji haszujących (skrótu) do zabezpieczania haseł, a także jak zrobić to efektywnie. Czemu hasła podawane przez użytkowników powinny być haszowane? Haszowanie haseł jest jedną z podstawowych metod zapewniania bezpieczeństwa, która musi być uwzględniona na etapie projektowania aplikacji lub usługi, która przyjmuje hasła od użytkowników. Bez haszowania dowolne przechowywane hasła mogą mogą paść ofiarą kradzieży w wypadku naruszenia źródła danych, a potem natychmiast użyte nie tylko do zaatakowania aplikacji lub usługi, ale także kont użytkowników w innych usługach, jeżeli nie używają oni unikalnych haseł. Stosując funkcję skrótu do haseł użytkowników przed ich zapisaniem, odgadnięcie oryginalnego hasła przez atakującego staje się niemal niewykonalne, a my wciąż będziemy mogli porównywać wynikowy hasz do oryginalnego hasła. Należy jednak zauważyć, że haszowanie haseł chroni jedynie przed ich wykradnięciem z miejsca przechowywania danych, ale już nie przed przechwyceniem przez złośliwy kod wstrzyknięty do samej aplikacji lub usługi. Dlaczego popularne funkcje haszujące jak md5 czy sha1 nie nadają się do haszowania haseł? Algorytmy haszujące takie jak MD5, SHA1 czy SHA256 zostały zaprojektowane tak, by były bardzo szybkie i wydajne. Przy użyciu nowoczesnych technik i sprzętu, trywialne stały się ataki typu brute force na wyniku działania tych funkcji tak, aby odgadnąć oryginalne dane wejściowe. Ze względu na to, jak szybko dzisiejsze komputery potrafią odwrócić te algorytmy haszujące, wielu profesjonalistów z zakresu bezpieczeństwa nie poleca ich stosowania do haszowania haseł. Jak powinny być haszowane hasła, jeśli popularne funkcje skrótu nie nadają się do tego? Podczas haszowania haseł dwa najważniejsze aspekty to koszt obliczeniowy oraz sól. Im bardziej kosztowny obliczeniowo jest algorytm haszujący, tym dłużej zajmie aby poddać wynik jego działania atakowi brute force. PHP udostępnia wbudowane API do haszowania haseł, które bezpiecznie obsługuje zarówno haszowanie oraz weryfikację haseł w poprawny sposób. Do haszowania haseł sugeruje się użycie algorytmu Blowfish, który jest także domyślnym algorytmem używanym przez API do haszowania haseł, jako że jest on zdecydowanie bardziej kosztowny obliczeniowo niż MD5 lub SHA1, a przy tym wciąż jest skalowalny. Do haszowania haseł może nadać się także funkcja crypt, ale sugeruje się jej wykorzystanie tylko w celu osiągnięcia kompatybilności z innymi systemami. Zamiast tego zdecydowanie zaleca się użycie wbudowanego API haszowania haseł, gdy tylko jest to możliwe. Czym jest sól? Sól kryptograficzna to dane, które są stosowane podczas procesu haszowania, aby uniemożliwić wyszukanie wyniku działania algorytmu na listach wcześniej obliczonych par haszy i ich danych wejściowych, znanych jako tęczowe tablice. W prostych słowach, sól to trochę dodatkowych danych, które powodują, że hasze stają się znacznie trudniejsze do złamania. Istnieje wiele usług online, które posiadają rozbudowane listy wcześniej obliczonych haszy oraz oryginalnych danych wejściowych dla tych haszy. użycie soli powoduje, że znalezienie wynikowego hasza na takich listach jest mało prawdopodobne lub wręcz niemożliwe. password_hash stworzy losową sól, jeśli nie została ona podana. Ogólnie rzecz biorąc jest to najprostsze i najbezpieczniejsze podejście. Jak przechowywana jest sól? Jeśli użyta została funkcja password_hash lub crypt, zwrócona przez nią wartość zawiera także sól jako element wygenerowanego hasza. Ta wartość powinna być zapisana w niezmienionej postaci w bazie danych, gdyż zawiera informacje o tym, jaka funkcja haszująca została wykorzystana do jej stworzenia i można taką wartość przekazać bezpośrednio do password_verify podczas weryfikacji hasła. Aby uniknąć ataków opartych o czas do sprawdzenia haseł powinna być zawsze wykorzystywana funkcja password_verify, a nie ponowne obliczenie hasza i porównanie wyników. Poniższy diagram pokazuje format wartości zwracanej przez crypt oraz password_hash. Jak widać jest ona samodzielna, zawiera wszystkie informacje na temat algorytmu oraz soli wymaganej do późniejszej weryfikacji hasła. Elementy wartości zwracanej przez funkcje password_hash oraz crypt to kolejno: wybrany algorytm, opcje algorytmu, wykorzystana sól oraz zahaszowane hasło.