Hashing-ul parolelor
Pentru a asigura securitatea utilizatorilor noștri, nu stocăm parolele lor în formă lizibilă, ci stocăm doar amprenta (așa-numitul hash). Din amprentă nu se poate reconstrui retroactiv forma originală a parolei. Este important să folosim un algoritm sigur pentru a crea amprenta. Cu aceasta ne ajută clasa Nette\Security\Passwords.
Framework-ul adaugă automat în containerul DI un serviciu de tip Nette\Security\Passwords
sub numele
security.passwords
, la care ajungeți solicitându-l prin injecția de dependențe.
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct ($algo=PASSWORD_DEFAULT, array $options=[]): string
Alegem ce algoritm sigur să folosim pentru generarea hash-ului și configurăm parametrii săi.
Implicit se folosește PASSWORD_DEFAULT
, adică alegerea algoritmului este lăsată pe seama PHP. Algoritmul se
poate schimba în versiunile mai noi de PHP, dacă apar algoritmi de hashing mai noi și mai puternici. De aceea, ar trebui să
fiți conștienți că lungimea hash-ului rezultat se poate schimba și ar trebui să îl stocați într-un mod care poate
conține suficiente caractere, 255 fiind lățimea recomandată.
Exemplu de setare a vitezei de hashing cu algoritmul bcrypt prin modificarea parametrului cost: (în 2020, implicit este 10, hashing-ul parolei durează aproximativ 80ms, pentru cost 11 este cca 160ms, pentru cost 12 aproximativ 320ms, cu cât este mai lent, cu atât protecția este mai bună, viteza 10–12 fiind deja considerată o protecție suficientă)
// vom hasha parolele cu 2^12 (2^cost) iterații ale algoritmului bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
Prin injecție de dependențe:
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
hash (string $passwords): string
Generează hash-ul parolei.
$res = $passwords->hash($password); // Hashează parola
Rezultatul $res
este un șir care, pe lângă hash-ul propriu-zis, conține și identificatorul algoritmului
folosit, setările sale și sarea criptografică (date aleatorii care asigură că pentru aceeași parolă se generează un hash
diferit). Este deci compatibil retroactiv, de exemplu, dacă schimbați parametrii, hash-urile stocate folosind setările
anterioare vor putea fi verificate. Întregul rezultat se stochează în baza de date, deci nu este nevoie să stocați sarea sau
setările separat.
verify (string $password, string $hash): bool
Verifică dacă parola dată corespunde amprentei date. Obțineți $hash
din baza de date pe baza numelui de
utilizator sau adresei de e-mail specificate.
if ($passwords->verify($password, $hash)) {
// parola corectă
}
needsRehash (string $hash): bool
Verifică dacă hash-ul corespunde opțiunilor specificate în constructor.
Este util de folosit în momentul în care, de exemplu, schimbați viteza de hashing. Verificarea se face conform setărilor
stocate și dacă needsRehash()
returnează true
, atunci este necesar să se creeze din nou hash-ul, de
data aceasta cu noii parametri, și să se salveze din nou în baza de date. Astfel se “actualizează” automat hash-urile
stocate la autentificarea utilizatorilor.
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// salvează $hash în baza de date
}