Haszowanie hasła
W celu zapewnienia bezpieczeństwa naszych użytkowników nie przechowujemy ich haseł w czytelnej formie, a jedynie przechowujemy odcisk palca (tzw. hash). Z odcisku palca nie da się odtworzyć oryginalnej postaci hasła. Ważne jest, aby do stworzenia odcisku palca użyć bezpiecznego algorytmu. Pomoże nam w tym klasa Nette\Security\Passwords.
Framework automatycznie dodaje usługę taką jak Nette\Security\Passwords
do kontenera DI pod nazwą
security.passwords
, do której możesz uzyskać dostęp, zlecając jej przekazanie za pomocą zastrzyku zależności.
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct ($algo=PASSWORD_DEFAULT, array $options=[]): string
Wybieramy, jaki bezpieczny algorytm generowania hashów zastosować i konfigurujemy jego parametry.
Domyślnie jest to PASSWORD_DEFAULT
, więc wybór algorytmu pozostawiamy PHP. Algorytm ten może ulec zmianie w
nowszych wersjach PHP, jeśli pojawią się nowsze, silniejsze algorytmy haszujące. Dlatego należy mieć świadomość, że
długość wynikowego hasha może się zmienić i należy go przechowywać w sposób, który może pomieścić wystarczająco
dużo znaków, 255 to zalecana szerokość.
Przykład ustawienia prędkości haszowania algorytmu bcrypt poprzez zmianę parametru cost: (w 2020 roku domyślnie 10, haszowanie hasła trwa około 80ms, dla kosztu 11 jest to około 160ms, dla kosztu 12 jest to około 320ms, im wolniej tym lepsze zabezpieczenie, a prędkość 10–12 jest już uważana za wystarczające zabezpieczenie)
// budeme hesla hashovat 2^12 (2^cost) iteracemi algorytmu bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
Wykorzystanie wstrzykiwania zależności:
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
hash (string $passwords): string
Generuje hash hasła.
$res = $passwords->hash($password); // Zahashuje heslo
Wynik, $res
, to ciąg znaków, który oprócz samego hasha zawiera identyfikator użytego algorytmu, jego
ustawienia oraz sól kryptograficzną (losowe dane zapewniające wygenerowanie innego hasha dla tego samego hasła). Dzięki temu
jest on kompatybilny wstecz, na przykład w przypadku zmiany parametrów można zweryfikować hashe zapisane przy użyciu
poprzednich ustawień. Cały ten wynik jest przechowywany w bazie danych, więc nie ma potrzeby przechowywania soli czy ustawień
osobno.
verify (string $password, string $hash): bool
Ustalenie, czy hasło pasuje do podanego odcisku palca. $hash
pobranie z bazy danych według podanej nazwy
użytkownika lub adresu e-mail.
if ($passwords->verify($password, $hash)) {
// poprawne hasło
}
needsRehash (string $hash): bool
Uzyskuje informację czy hash pasuje do opcji określonych w konstruktorze.
Przydatne, gdy na przykład zmieniasz szybkość haszowania. Sprawdzi się w stosunku do zapisanych ustawień i jeśli
needsRehash()
zwróci true
, to musisz odtworzyć hash, tym razem z nowymi parametrami i ponownie
zapisać go w bazie danych. W ten sposób zapisane hashe są automatycznie “aktualizowane”, gdy użytkownicy się logują.
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// uložit $hash do databáze
}