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.

Installazione e requisiti

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
}
versione: 4.0