Nigdy nie powinieneś uciekać, przycinać ani używać żadnego innego mechanizmu czyszczenia haseł, które będziesz haszować z PHP z password_hash()
wielu powodów, z których największym jest to, że dodatkowe czyszczenie hasła wymaga niepotrzebnego dodatkowego kodu.
Będziesz argumentował (i widzisz to w każdym poście, w którym dane użytkownika są akceptowane do wykorzystania w twoich systemach), że powinniśmy wyczyścić wszystkie dane wejściowe użytkownika i miałbyś rację w przypadku każdej innej informacji, którą akceptujemy od naszych użytkowników. Hasła są różne. Hasła haszowane nie mogą stwarzać żadnego zagrożenia iniekcją SQL, ponieważ ciąg znaków jest zamieniany na hash przed zapisaniem w bazie danych.
Haszowanie hasła to czynność polegająca na zabezpieczeniu hasła podczas przechowywania w bazie danych. Funkcja skrótu nie nadaje specjalnego znaczenia żadnym bajtom, więc ze względów bezpieczeństwa nie jest wymagane czyszczenie jej danych wejściowych
Jeśli podążasz za mantrami pozwalającymi użytkownikom na używanie haseł / fraz, których pragną, i nie ograniczasz haseł , zezwalając na dowolną długość, dowolną liczbę spacji i haszowanie znaków specjalnych, sprawi, że hasło / hasło będzie bezpieczne bez względu na to, co jest w nim zawarte hasło. Obecnie najpopularniejszy hash (domyślny) PASSWORD_BCRYPT
zamienia hasło w ciąg o szerokości 60 znaków zawierający losową sól wraz z zaszyfrowanymi informacjami o haśle i kosztem (algorytmicznym kosztem utworzenia skrótu):
PASSWORD_BCRYPT służy do tworzenia nowych skrótów haseł przy użyciu algorytmu CRYPT_BLOWFISH. Powoduje to zawsze haszowanie w formacie krypt „$ 2y $”, który zawsze ma 60 znaków szerokości.
Wymagania dotyczące miejsca do przechowywania skrótu mogą ulec zmianie, ponieważ do funkcji dodawane są różne metody haszowania, dlatego zawsze lepiej jest zwiększyć typ kolumny dla przechowywanego skrótu, na przykład VARCHAR(255)
lub TEXT
.
Możesz użyć pełnego zapytania SQL jako hasła i zostanie ono zaszyfrowane, co uniemożliwi jego wykonanie przez silnik SQL, np.
SELECT * FROM `users`;
Może być hashowany $2y$10$1tOKcWUWBW5gBka04tGMO.BH7gs/qjAHZsC5wyG0zmI2C.KgaqU5G
Zobaczmy, jak różne metody odkażania wpływają na hasło -
Hasło to I'm a "dessert topping" & a <floor wax>!
(na końcu hasła jest 5 spacji, które nie są tutaj wyświetlane).
Kiedy stosujemy następujące metody przycinania, uzyskujemy różne wyniki:
var_dump(trim($_POST['upassword']));
var_dump(htmlentities($_POST['upassword']));
var_dump(htmlspecialchars($_POST['upassword']));
var_dump(addslashes($_POST['upassword']));
var_dump(strip_tags($_POST['upassword']));
Wyniki:
string(40) "I'm a "dessert topping" & a <floor wax>!" // spaces at the end are missing
string(65) "I'm a "dessert topping" & a <floor wax>! " // double quotes, ampersand and braces have been changed
string(65) "I'm a "dessert topping" & a <floor wax>! " // same here
string(48) "I\'m a \"dessert topping\" & a <floor wax>! " // escape characters have been added
string(34) "I'm a "dessert topping" & a ! " // looks like we have something missing
Co się stanie, gdy wyślemy je do password_hash()
? Wszystkie są zaszyfrowane, tak jak w przypadku powyższego zapytania. Problem pojawia się, gdy próbujesz zweryfikować hasło. Jeśli zastosujemy jedną lub więcej z tych metod, musimy je ponownie zastosować przed ich porównaniem password_verify()
. Poniższe zawiodłyby:
password_verify($_POST['upassword'], $hashed_password); // where $hashed_password comes from a database query
Będziesz musiał uruchomić przesłane hasło za pomocą wybranej metody czyszczenia, zanim użyjesz wyniku tego do weryfikacji hasła. Jest to niepotrzebny zestaw kroków i nie sprawi, że hash nie będzie lepszy.
Używasz wersji PHP mniejszej niż 5.5? Możesz użyć password_hash()
pakietu zgodności .
Naprawdę nie powinieneś używać skrótów haseł MD5 .