Hachage de mot de passe

Pour gérer la sécurité de nos utilisateurs, nous ne stockons jamais leurs mots de passe en clair, nous stockons plutôt le hachage du mot de passe. Le hachage n'est pas une opération réversible, le mot de passe ne peut pas être récupéré. Le mot de passe peut cependant être craqué et pour rendre le craquage aussi difficile que possible, nous devons utiliser un algorithme sécurisé. La classe Nette\Security\Passwords nous aidera à le faire.

Installation et configuration requise

Le framework ajoute automatiquement un service Nette\Security\Passwords au conteneur DI sous le nom security.passwords, que vous obtenez en le passant en utilisant l'injection de dépendance:

use Nette\Security\Passwords;

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

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

Choisit l'algorithme sécurisé utilisé pour le hachage et comment le configurer.

La valeur par défaut est PASSWORD_DEFAULT, donc le choix de l'algorithme est laissé à PHP. L'algorithme peut changer dans les nouvelles versions de PHP lorsque de nouveaux algorithmes de hachage plus puissants sont supportés. Vous devez donc être conscient que la longueur du hachage résultant peut changer. Vous devez donc stocker le hachage résultant de manière à pouvoir stocker suffisamment de caractères, 255 étant la largeur recommandée.

Voici comment utiliser l'algorithme bcrypt et modifier la vitesse de hachage en utilisant le paramètre cost à partir de la valeur par défaut de 10. En 2020, avec le coût 10, le hachage d'un mot de passe prend environ 80 ms, le coût 11 prend 160 ms, le coût 12 320 ms, l'échelle étant logarithmique. Plus c'est lent, mieux c'est, le coût 10–12 est considéré comme suffisamment lent pour la plupart des cas d'utilisation :

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

Avec l'injection de dépendances :

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

hash(string $passwords): string

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

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

Le résultat $res est une chaîne de caractères qui, en plus du hachage lui-même, contient l'identifiant de l'algorithme utilisé, ses paramètres et le sel cryptographique (données aléatoires permettant de s'assurer qu'un hachage différent est généré pour le même mot de passe). Il est donc rétrocompatible, par exemple, si vous modifiez les paramètres, les hachages stockés à l'aide des réglages précédents peuvent être vérifiés. L'ensemble du 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

Détermine si le mot de passe donné correspond au hachage donné. Obtenez le $hash de la base de données par nom d'utilisateur ou adresse e-mail.

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

needsRehash(string $hash): bool

Vérifie si le hachage correspond aux options données dans le constructeur.

Utilisez cette méthode lorsque vous modifiez par exemple les paramètres de hachage. La vérification du mot de passe utilisera les paramètres stockés avec le hachage et si needsRehash() retourne vrai, vous devez calculer à nouveau le hachage, cette fois avec les paramètres mis à jour, et le stocker à nouveau dans la base de données. Cela garantit que les hachages de mots de passe seront automatiquement “mis à jour” lorsque les utilisateurs se connecteront.

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