Hachage de mots de passe

Pour assurer la sécurité de nos utilisateurs, nous ne stockons pas leurs mots de passe en clair, mais nous enregistrons uniquement leur empreinte (appelée hash). Il est impossible de reconstruire le mot de passe original à partir de l'empreinte. Il est important d'utiliser un algorithme sécurisé pour créer l'empreinte. La classe Nette\Security\Passwords nous aide pour cela.

Installation et prérequis

Le framework ajoute automatiquement au conteneur DI un service de type Nette\Security\Passwords sous le nom security.passwords, auquel vous pouvez accéder en le faisant passer via l'injection de dépendances.

use Nette\Security\Passwords;

class Foo
{
	public function __construct(
		private Passwords $passwords,
	) {
	}
}

__construct ($algo=PASSWORD_DEFAULT, array $options=[])string

Nous choisissons quel algorithme sécurisé utiliser pour générer le hash et configurons ses paramètres.

Par défaut, PASSWORD_DEFAULT est utilisé, c'est-à-dire que le choix de l'algorithme est laissé à PHP. L'algorithme peut changer dans les nouvelles versions de PHP si de nouveaux algorithmes de hachage plus forts apparaissent. Par conséquent, vous devez être conscient que la longueur du hash résultant peut changer, et vous devez le stocker d'une manière qui peut accueillir suffisamment de caractères, 255 est la largeur recommandée.

Exemple de réglage de la vitesse de hachage avec l'algorithme bcrypt en modifiant le paramètre cost : (en 2020, la valeur par défaut est 10, le hachage du mot de passe prend environ 80 ms, pour cost 11 c'est environ 160 ms, pour cost 12 environ 320 ms, plus c'est lent, meilleure est la protection, la vitesse 10–12 étant déjà considérée comme une protection suffisante)

// nous hacherons les mots de passe avec 2^12 (2^cost) itérations de l'algorithme bcrypt
$passwords = new Passwords(PASSWORD_BCRYPT, ['cost' => 12]);

Via l'injection de dépendances :

services:
	security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])

hash (string $passwords): string

Génère le hash du mot de passe.

$res = $passwords->hash($password); // Hache le mot de passe

Le résultat $res est une chaîne qui, en plus du hash lui-même, contient également l'identifiant de l'algorithme utilisé, ses paramètres et le sel cryptographique (données aléatoires garantissant que pour le même mot de passe, un hash différent sera généré). Il est donc rétrocompatible, par exemple, si vous modifiez les paramètres, les hashes stockés avec les paramètres précédents pourront toujours être vérifiés. L'ensemble de ce résultat est stocké dans la base de données, il n'est donc pas nécessaire de stocker le sel ou les paramètres séparément.

verify (string $password, string $hash)bool

Vérifie si le mot de passe donné correspond à l'empreinte donnée. Obtenez $hash de la base de données en fonction du nom d'utilisateur ou de l'adresse e-mail fournie.

if ($passwords->verify($password, $hash)) {
	// mot de passe correct
}

needsRehash (string $hash): bool

Vérifie si le hash correspond aux options spécifiées dans le constructeur.

Il est utile de l'utiliser lorsque, par exemple, vous modifiez la vitesse de hachage. La vérification est effectuée selon les paramètres enregistrés et si needsRehash() renvoie true, il est nécessaire de recréer le hash, cette fois avec les nouveaux paramètres, et de le réenregistrer dans la base de données. De cette manière, les hashes stockés sont automatiquement “mis à niveau” lors de la connexion des utilisateurs.

if ($passwords->needsRehash($hash)) {
	$hash = $passwords->hash($password);
	// enregistrer $hash dans la base de données
}
version: 4.0