Hashing delle password
Per garantire la sicurezza dei nostri utenti, non memorizziamo le loro password in forma leggibile, ma memorizziamo solo l'impronta (il cosiddetto hash). Dall'impronta non è possibile ricostruire la forma originale della password. È importante utilizzare un algoritmo sicuro per creare l'impronta. In questo ci aiuta la classe Nette\Security\Passwords.
Il framework aggiunge automaticamente al container DI un servizio di tipo Nette\Security\Passwords
con il nome
security.passwords
, al quale potete accedere facendovelo passare tramite dependency injection.
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct ($algo=PASSWORD_DEFAULT, array $options=[]): string
Scegliamo quale algoritmo sicuro utilizzare per generare l'hash e ne configuriamo i parametri.
Come predefinito si usa PASSWORD_DEFAULT
, ovvero la scelta dell'algoritmo viene lasciata a PHP. L'algoritmo può
cambiare nelle versioni più recenti di PHP, se compaiono algoritmi di hashing più nuovi e più forti. Pertanto, dovreste essere
consapevoli che la lunghezza dell'hash risultante può cambiare e dovreste memorizzarlo in un modo che possa contenere abbastanza
caratteri, 255 è la larghezza consigliata.
Esempio di impostazione della velocità di hashing con l'algoritmo bcrypt modificando il parametro cost: (nel 2020 il valore predefinito è 10, l'hashing della password richiede circa 80 ms, per cost 11 circa 160 ms, per cost 12 circa 320 ms, più è lento, migliore è la protezione, mentre la velocità 10–12 è già considerata una protezione sufficiente)
// hasheremo le password con 2^12 (2^cost) iterazioni dell'algoritmo bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
Tramite dependency injection:
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
hash (string $passwords): string
Genera l'hash della password.
$res = $passwords->hash($password); // Hasha la password
Il risultato $res
è una stringa che, oltre all'hash stesso, contiene anche l'identificatore dell'algoritmo
utilizzato, le sue impostazioni e il salt crittografico (dati casuali che garantiscono che per la stessa password venga generato
un hash diverso). È quindi retrocompatibile, ad esempio se cambiate i parametri, anche gli hash memorizzati utilizzando le
impostazioni precedenti potranno essere verificati. L'intero risultato viene memorizzato nel database, quindi non è necessario
memorizzare separatamente il salt o le impostazioni.
verify (string $password, string $hash): bool
Verifica se la password data corrisponde all'impronta data. Ottenete $hash
dal database in base al nome utente
o all'indirizzo e-mail specificato.
if ($passwords->verify($password, $hash)) {
// password corretta
}
needsRehash (string $hash): bool
Verifica se l'hash corrisponde alle opzioni specificate nel costruttore.
È utile utilizzarlo nel momento in cui, ad esempio, si cambia la velocità di hashing. La verifica avviene in base alle
impostazioni memorizzate e se needsRehash()
restituisce true
, è necessario creare nuovamente l'hash,
questa volta con i nuovi parametri, e memorizzarlo nuovamente nel database. In questo modo gli hash memorizzati vengono
automaticamente “aggiornati” al momento del login degli utenti.
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// memorizzare $hash nel database
}