Hachage des mots de passe
Pour garantir la sécurité de nos utilisateurs, nous ne stockons jamais leurs mots de passe sous forme lisible, mais seulement leur empreinte (appelée hachage). Le hachage ne peut pas être inversé pour retrouver le mot de passe d'origine. Il est important d'utiliser un algorithme sûr pour créer le hachage. La classe Nette\Security\Passwords nous y aide.
Le framework ajoute automatiquement au conteneur DI un service de type Nette\Security\Passwords sous le nom
security.passwords. Vous pouvez vous le faire passer par injection de dépendances.
use Nette\Security\Passwords;
class Foo
{
public function __construct(
private Passwords $passwords,
) {
}
}
__construct (string $algo=PASSWORD_DEFAULT, array $options=[])
Nous choisissons quel algorithme sûr utiliser pour générer le hachage et nous en configurons les paramètres.
La valeur par défaut est PASSWORD_DEFAULT, ce qui signifie que le choix de l'algorithme est laissé à PHP.
L'algorithme peut changer dans des versions plus récentes de PHP si des algorithmes de hachage plus récents et plus robustes
apparaissent. Sachez donc que la longueur du hachage obtenu peut changer et stockez-le d'une façon qui puisse accueillir assez de
caractères ; 255 est la largeur recommandée.
Exemple de réglage de la vitesse de hachage de l'algorithme bcrypt en modifiant le paramètre cost : (en 2020, la valeur par défaut est 10, hacher un mot de passe prend environ 80 ms ; pour cost 11, environ 160 ms ; pour cost 12, environ 320 ms ; plus c'est lent, meilleure est la protection, une vitesse de 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]);
À l'aide de l'injection de dépendances :
services:
security.passwords: Nette\Security\Passwords(::PASSWORD_BCRYPT, [cost: 12])
static bcrypt (?int $cost=null): Passwords
Crée une instance configurée pour l'algorithme bcrypt. Le paramètre $cost fixe la vitesse de hachage décrite
ci-dessus ; si vous l'omettez, la valeur par défaut de PHP est utilisée.
$passwords = Passwords::bcrypt(12);
static argon2id (?int $memoryCost=null, ?int $timeCost=null, ?int $threads=null): Passwords
Crée une instance configurée pour l'algorithme Argon2id. Les paramètres omis sont laissés aux valeurs par défaut de PHP.
Si PHP a été compilé sans la prise en charge d'Argon2, la méthode lève Nette\NotSupportedException.
$passwords = Passwords::argon2id(memoryCost: 1 << 17, timeCost: 4);
hash (string $password): 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 qui, outre le hachage lui-même, contient l'identifiant de l'algorithme
utilisé, ses réglages et un sel cryptographique (des données aléatoires garantissant qu'un hachage différent est produit pour
le même mot de passe). Il est donc rétrocompatible : si vous changez par exemple les paramètres, les hachages stockés avec les
réglages précédents restent vérifiables. C'est tout ce résultat qui est stocké en base, il n'est donc pas nécessaire d'y
conserver séparément le sel ou les réglages.
verify (string $password, string $hash): bool
Détermine si le mot de passe donné correspond au hachage donné. Obtenez $hash depuis la base d'après le nom
d'utilisateur ou l'adresse e-mail saisis.
if ($passwords->verify($password, $hash)) {
// mot de passe correct
}
needsRehash (string $hash): bool
Détermine si le hachage correspond aux options indiquées dans le constructeur.
Il est utile de s'en servir lorsque vous changez, par exemple, le cost du hachage. La vérification se fait d'après les
réglages stockés et, si needsRehash() renvoie true, il faut créer le hachage à nouveau, cette fois
avec les nouveaux paramètres, et l'enregistrer de nouveau en base. Cela “met à niveau” automatiquement les hachages stockés
lorsque les utilisateurs se connectent.
if ($passwords->needsRehash($hash)) {
$hash = $passwords->hash($password);
// enregistrer $hash dans la base
}