Przechowywanie haseł

PHP przechowywanie hasełPrzechowywanie haseł użytkowników aplikacji wydaje się banalną sprawą. Wystarczy zapisać gdzieś (przeważnie w bazie danych) hasło i już po sprawie. Jednak bezpośrednie zapisanie hasła użytkownika to najgorsze z możliwych rozwiązań, niestety nadal przez wielu stosowane. Istnieją inne lepsze sposoby, które postaram się tutaj opisać.

Sposoby przechowywania haseł

Ogólnie rzecz ujmując hasła możemy przechowywać:

  • w postaci jawnej
  • w postaci niejawnej
    • szyfrowane
    • hashowane

Hasła w postaci jawnej

Przechowywanie hasła w postaci jawnej nie daje żadnego bezpieczeństwa. W wyniku błędów, niedostatecznego zabezpieczenie lub innych okoliczności baza zawierająca hasła może wyciec. Taka sytuacja będzie oznaczać automatyczne ujawnienie wszystkich haseł, co dyskwalifikuje tą metodę. Pozostaje więc przechowywanie haseł w postaci niejawnej.

Hasła w postaci niejawnej

Jeśli zaszyfrujemy hasła, to gdzieś będziemy musieli przechowywać klucz pozwalający je odszyfrować. Bezpieczne przechowywanie klucza szyfrującego nie jest prostym zadaniem. W wielu przypadkach może nawet nie być to możliwe. Jeżeli klucz wycieknie razem z bazą, to ten sposób zabezpieczenia haseł też na niewiele się zda.

Dobrą metoda przechowywania haseł jest ich hashowanie. Najczęściej w tym celu używane są funkcje skrótu takie jak MD5 czy funkcje z rodziny SHA. Funkcje te są funkcjami jednokierunkowymi – na podstawie wyniku funkcji nie można obliczyć danych wejściowych. Generowany przez nie wynik ma stałą długość, niezależną od długości danych wejściowych. Jak widać jest to odwzorowanie ze zbioru nieskończonego na zbiór skończony, zatem funkcja ta nie jest różnowartościowa. Dla dwóch różnych danych wejściowych może wygenerować tą samą wartość wynikową. Sytuacje takie nazywane są kolizją.

Łamanie hashy

Jest wiele algorytmów hashujących. Jednak nie są one uniwersalne. To co może być zaletą w jednych zastosowaniach, może być jednocześnie wada w innych. Szybkość działania jest zaletą przy obliczaniu sum kontrolnych np. plików, w przypadku haseł przyśpieszy to „łamanie” hashy. W projektowaniu algorytmów takich jak MD5, SHA-1, SHA-2 (SHA-224, SHA-256, SHA-384, SHA-512, SHA-512/224, SHA-512/256), SHA-3 (również kilka wariantów) pod uwagę była brana szybkość działania. MD5 nie jest uważany za bezpieczny do większości zastosowań – znane są skuteczne metody pozwalające na szybkie znalezienie kolizji. Znane są teoretyczne ataki na SHA-1, jednak w praktyce nadal są one zbyt czasochłonne w realizacji.

Ze względu na to, że nie istnieje przekształcenie pozwalające na uzyskanie z hasha oryginalnego hasła, atakujący musi podejść do problemu z drugiej strony. Dla znanego hasła obliczyć hash i porównać go z tym który chce złamać. Zatem do łamania hashy można zastosować atak brute force lub słownikowy. Kluczową kwestią tego rodzaju ataków jest to, ile haseł w danym czasie czasu będzie mógł sprawdzić atakujący. Czym więcej tym szybciej może osiągnąć cel.

Innego rodzaju atakiem jest użycie tablic tęczowych. Atak ten pozwala zaoszczędzić czas kosztem miejsca na dysku zajmowanego przez tablice. W internecie można znaleźć gotowe tablice dla różnych długości haseł, zestawów znaków i algorytmów. Dobrym zabezpieczeniem przed tego rodzaju atakami jest użycie soli (losowej wartości) która wraz z hasłem będzie podstawą do obliczania hasha hasła. Sól powinna być inna dla każdego hasła, zapisuje się ją razem z hasłem. Im będzie ona dłuższa tym lepiej.

Należy mieć na uwadze, że solenie haseł nie chroni przed atakami słownikowymi i brute force. Aby chronić się przed tego typu atakami, czas obliczeń musi być stosunkowo długi. W tym celu warto zastosować algorytmy biorące to pod uwagę.

Dobre algorytmy

Wartymi uwagi algorytmami przystosowanymi specjalnie do hashowania haseł, używającymi soli są:

  • PBKDF2 (Password-Based Key Derivation Function 2)
  • bcrypt – oparty na dość powolnym algorytmie szyfrującym Blowfish
  • scrypt – został zaprojektowany tak aby używał dużą ilość pamięci w porównaniu z innymi tego typu algorytmami. Istnieje możliwość zmniejszenia użycia pamięci kosztem większych wymagań obliczeniowych, a co za tym idzie spowolnieniem obliczeń.

Najlepszym wydaje się scrypt, chociaż bcrypt jest również warty szczególnej uwagi.

Implementacje w PHP

PHP od wersji 5.5.0 posiada wbudowaną obsługę PBKDF2, jest on zaimplementowany w funkcji hash_pbkdf2(). W tej samej wersji PHP wprowadzono również bcrypt. Jest on domyślnym algorytmem używanym w funkcji password_hash(). Niestety póki co scrypt nie jest dostępny w PHP, można jedynie skorzystać z implementacji napisanych w tym języku np. php-scrypt.

Dodaj komentarz

Twój adres e-mail nie zostanie opublikowany. Wymagane pola są oznaczone *

To prevent spam, URLs are not allowed in comments. All comments are moderated and subject to approval.
Aby zapobiec spamowi, adresy URL nie są dozwolone w komentarzach. Wszystkie komentarze są moderowane i podlegają zatwierdzeniu.