Hashing delle password
Per gestire la sicurezza dei nostri utenti, non memorizziamo mai le loro password in chiaro, bensì l'hash della password. L'hash non è un'operazione reversibile, la password non può essere recuperata. La password può però essere decifrata e per renderla il più difficile possibile dobbiamo usare un algoritmo sicuro. La classe Nette\Security\Passwords ci aiuterà in questo.
Il framework aggiunge automaticamente un servizio Nette\Security\Passwords
al contenitore DI con il nome
security.passwords
, che si ottiene passandoglielo tramite dependency injection:
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct ($algo=PASSWORD_DEFAULT, array $options=[]): string
Sceglie quale algoritmo sicuro utilizzare per l'hashing e come configurarlo.
L'impostazione predefinita è PASSWORD_DEFAULT
, quindi la scelta dell'algoritmo è lasciata a PHP. L'algoritmo
può cambiare nelle nuove versioni di PHP, quando vengono supportati algoritmi di hashing più potenti. Pertanto, si deve essere
consapevoli che la lunghezza dell'hash risultante può cambiare. Pertanto, è necessario memorizzare l'hash risultante in un modo
che possa memorizzare un numero sufficiente di caratteri; 255 è la larghezza consigliata.
In questo modo si utilizza l'algoritmo bcrypt e si modifica la velocità di hashing utilizzando il parametro cost rispetto al valore predefinito 10. Nell'anno 2020, con il costo 10, l'hashing di una password richiede circa 80 ms, il costo 11 richiede 160 ms, il costo 12 320 ms, la scala è logaritmica. Più lento è meglio è, il costo 10–12 è considerato abbastanza lento per la maggior parte dei casi d'uso:
// faremo l'hash delle password con 2^12 (2^cost) iterazioni dell'algoritmo bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);
Con l'iniezione di dipendenza:
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
hash (string $passwords): string
Genera l'hash della password.
$res = $passwords->hash($password); // Fa il hash della password
Il risultato $res
è una stringa che, oltre all'hash stesso, contiene l'identificatore dell'algoritmo utilizzato,
le sue impostazioni e il sale crittografico (dati casuali per garantire che venga generato un hash diverso per la stessa
password). È quindi retrocompatibile: ad esempio, se si cambiano i parametri, è possibile verificare gli hash memorizzati con
le impostazioni precedenti. L'intero risultato è memorizzato nel database, quindi non è necessario memorizzare separatamente il
sale o le impostazioni.
verify (string $password, string $hash): bool
Scopre se la password data corrisponde all'hash dato. Ottiene $hash
dal database in base al nome utente
o all'indirizzo e-mail.
if ($passwords->verify($password, $hash)) {
// Password corretta
}
needsRehash (string $hash): bool
Scopre se l'hash corrisponde alle opzioni fornite nel costruttore.
Utilizzare questo metodo quando, ad esempio, si cambiano i parametri dell'hash. La verifica della password utilizzerà
i parametri memorizzati con l'hash e se needsRehash()
restituisce true, è necessario calcolare nuovamente l'hash,
questa volta con i parametri aggiornati, e memorizzarlo nuovamente nel database. Questo assicura che gli hash delle password
vengano automaticamente “aggiornati” quando gli utenti effettuano l'accesso.
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// memorizza $hash nel database
}