O ile jest to bezpieczniejsze niż zwykły MD5 ? Właśnie zacząłem zajmować się bezpieczeństwem hasłem. Jestem całkiem nowy w PHP.
$salt = 'csdnfgksdgojnmfnb';
$password = md5($salt.$_POST['password']);
$result = mysql_query("SELECT id FROM users
WHERE username = '".mysql_real_escape_string($_POST['username'])."'
AND password = '$password'");
if (mysql_num_rows($result) < 1) {
/* Access denied */
echo "The username or password you entered is incorrect.";
}
else {
$_SESSION['id'] = mysql_result($result, 0, 'id');
#header("Location: ./");
echo "Hello $_SESSION[id]!";
}
Odpowiedzi:
Najłatwiejszym sposobem zabezpieczenia schematu przechowywania haseł jest użycie biblioteki standardowej .
Ponieważ zabezpieczenia wydają się być o wiele bardziej skomplikowane i mają więcej niewidocznych możliwości zepsucia, niż większość programistów mogłaby rozwiązać samodzielnie, korzystanie z biblioteki standardowej jest prawie zawsze najłatwiejszą i najbezpieczniejszą (jeśli nie jedyną) dostępną opcją.
Nowy interfejs API haseł PHP (5.5.0+)
Jeśli używasz PHP w wersji 5.5.0 lub nowszej, możesz użyć nowego uproszczonego interfejsu API do mieszania haseł
Przykład kodu używającego API haseł PHP:
(Jeśli nadal używasz starszej wersji 5.3.7 lub nowszej, możesz zainstalować ircmaxell / password_compat, aby mieć dostęp do wbudowanych funkcji)
Poprawa po solonych haszyszach: dodaj pieprz
Jeśli chcesz dodatkowego bezpieczeństwa, specjaliści od bezpieczeństwa teraz (2017) zalecają dodanie „ pieprzu ” do (automatycznie) zasolonych skrótów haseł.
Jest prosta, upuszczona klasa, która bezpiecznie implementuje ten wzorzec, polecam: Netsilik / PepperedPasswords ( github ).
Pochodzi z licencją MIT, więc możesz go używać w dowolny sposób, nawet w projektach zastrzeżonych.
Przykład kodu wykorzystującego
Netsilik/PepperedPasswords
:Stara biblioteka standardowa
Spójrz na: Przenośny framework do haszowania haseł PHP : phpass i upewnij się, że używasz
CRYPT_BLOWFISH
algorytmu, jeśli to w ogóle możliwe.Przykład kodu wykorzystującego phpass (v0.2):
PHPass został zaimplementowany w kilku dobrze znanych projektach:
Dobrą rzeczą jest to, że nie musisz martwić się o szczegóły, te szczegóły zostały zaprogramowane przez ludzi z doświadczeniem i sprawdzone przez wiele osób w Internecie.
Aby uzyskać więcej informacji na temat schematów przechowywania haseł, przeczytaj wpis w blogu Jeffa : Prawdopodobnie przechowujesz hasła nieprawidłowo
Cokolwiek zrobisz, jeśli zdecydujesz się na podejście „ Zrobię to sam, dziękuję ”, nie używaj
MD5
lubSHA1
więcej . Są niezłym algorytmem mieszającym, ale ze względów bezpieczeństwa uważa się, że jest uszkodzony .Obecnie najlepszym rozwiązaniem jest używanie crypt z CRYPT_BLOWFISH.
CRYPT_BLOWFISH w PHP to implementacja skrótu Bcrypt. Bcrypt jest oparty na szyfrze blokowym Blowfish, wykorzystując kosztowną konfigurację klucza, aby spowolnić algorytm.
źródło
Twoi użytkownicy będą znacznie bezpieczniejsi, jeśli użyjesz zapytań parametrycznych zamiast łączenia instrukcji SQL. I sól powinna być unikalna dla każdego użytkownika i powinny być przechowywane razem z hash hasła.
źródło
Lepszym sposobem byłoby posiadanie unikalnej soli przez każdego użytkownika.
Zaletą posiadania soli jest to, że utrudnia napastnikowi wstępne wygenerowanie sygnatury MD5 każdego słowa w słowniku. Ale jeśli napastnik dowie się, że masz ustaloną sól, może następnie wstępnie wygenerować sygnaturę MD5 każdego słowa słownikowego poprzedzonego ustaloną solą.
Lepszym sposobem jest za każdym razem, gdy użytkownik zmienia swoje hasło, system generuje losową sól i przechowuje tę sól wraz z rekordem użytkownika. Sprawdzenie hasła jest nieco droższe (ponieważ musisz sprawdzić sól, zanim będziesz mógł wygenerować podpis MD5), ale znacznie utrudni atakującemu wstępne wygenerowanie MD5.
źródło
crypt()
funkcji). A ponieważ i tak musisz pobrać skrót hasła, użycie soli specyficznej dla użytkownika nie spowoduje, że procedura będzie droższa. (A może miałeś na myśli generowanie nowej losowej soli jest drogie? Naprawdę nie sądzę). W przeciwnym razie +1.W przypadku PHP 5.5 (to, co opisuję, jest dostępne dla jeszcze wcześniejszych wersji, patrz poniżej) tuż za rogiem chciałbym zasugerować użycie jego nowego, wbudowanego rozwiązania:
password_hash()
ipassword_verify()
. Zapewnia kilka opcji umożliwiających osiągnięcie wymaganego poziomu bezpieczeństwa hasła (na przykład poprzez określenie parametru „koszt” w$options
tablicy)wróci
Jak widać, ciąg zawiera sól, a także koszt określony w opcjach. Zawiera również zastosowany algorytm.
Dlatego podczas sprawdzania hasła (na przykład podczas logowania użytkownika), podczas korzystania z bezpłatnego
password_verify()
funkcji wyodrębni niezbędne parametry kryptograficzne z samego skrótu hasła.Jeśli nie określisz soli, wygenerowany skrót hasła będzie inny przy każdym wywołaniu
password_hash()
ponieważ sól jest generowana losowo. Dlatego porównanie poprzedniego skrótu z nowo wygenerowanym zakończy się niepowodzeniem, nawet w przypadku poprawnego hasła.Weryfikacja działa w ten sposób:
Mam nadzieję, że udostępnienie tych wbudowanych funkcji wkrótce zapewni lepsze bezpieczeństwo hasła w przypadku kradzieży danych, ponieważ zmniejsza ilość myśli, jaką programista musi włożyć w właściwą implementację.
Istnieje mała biblioteka (jeden plik PHP), która da ci PHP 5.5
password_hash
w PHP 5.3.7+: https://github.com/ircmaxell/password_compatźródło
password_hash()
ipassword_verify
bez względu na to, jakiego hasła (poprawnego czy nie),Dla mnie w porządku. Pan Atwood napisał o sile MD5 przeciwko tęczowym stołom , a właściwie z taką długą solą siedzisz ładnie (choć niektóre przypadkowe znaki interpunkcyjne / cyfry mogą to poprawić).
Możesz również przyjrzeć się SHA-1, który wydaje się być obecnie coraz bardziej popularny.
źródło
Chcę dodać:
Aby zapewnić kompatybilność ze starymi systemami, często ustawia się limit maksymalnej długości hasła. To jest zła zasada bezpieczeństwa: jeśli ustawisz ograniczenie, ustaw je tylko na minimalną długość haseł.
W celu odzyskania zapomnianego hasła należy przesłać adres, pod którym użytkownik może zmienić hasło.
Skrót hasła może być nieaktualny (parametry algorytmu mogą zostać zaktualizowane). Korzystając z funkcji
password_needs_rehash()
możesz to sprawdzić.źródło