Argon2id expliqué : ce que signifient m, t et p et quoi choisir

Argon2id est une fonction de hachage de mots de passe qui oblige chaque essai à utiliser une quantité fixe de mémoire, ce qui rend les essais à grande échelle sur GPU coûteux. Vous réglez la mémoire (m), les passes (t) et les voies (p). La RFC 9106 recommande m=2 GiB, t=1, p=4, ou m=64 MiB, t=3, p=4 avec moins de mémoire. Le minimum d'OWASP est m=19 MiB, t=2, p=1. Un mot de passe faible tombe quand même.

Mis à jour le . Outil en ligne de commande argon2 et argon2-cffi 25.1.0 dans un venv Python, sur un Mac Apple M6.

Pourquoi la mémoire compte

Quand un attaquant vole des hachages de mots de passe ou un coffre chiffré, il fait ses essais hors ligne, aussi vite que son matériel le permet. Un GPU a des milliers de petits cœurs : une fonction qui demande peu de mémoire, comme PBKDF2, tourne donc sur beaucoup d'entre eux à la fois.

Argon2 exige un bloc de mémoire pour chaque essai, et on ne peut pas s'en dispenser à bas prix. Or la mémoire est ce qui manque sur un GPU. En simple arithmétique, pas en benchmark : une carte de 24 GiB loge environ 96 essais simultanés à 256 MiB chacun, et environ 1 290 à 19 MiB. PBKDF2 ne fixe aucune limite de ce genre.

Il existe trois variantes. Argon2d résiste le mieux aux GPU, mais ses accès mémoire dépendent du mot de passe, ce qui peut fuiter par des canaux auxiliaires. Argon2i évite cela, au prix d'une moindre résistance aux GPU. Argon2id commence comme Argon2i pendant la première moitié de la première passe, puis fonctionne comme Argon2d. La RFC 9106 le recommande par défaut.

Les paramètres

NomSignificationEffet
mMémoire, en KiBLa défense principale. À augmenter en premier.
tPasses sur la mémoirePlus de temps pour chaque essai.
pVoies, pour les threads parallèlesPermet à un appareil avec plus de cœurs de remplir la mémoire plus vite. N'ajoute pas de mémoire.
SelValeur aléatoire par mot de passeMême mot de passe, hachage différent. Pas secret, stocké en clair. 16 octets suffisent pour tous les usages, dit la RFC.
Longueur du tagTaille de la sortie16 octets suffisent pour la plupart des usages. 32 est courant quand cela devient une clé.

Quelles valeurs utiliser

SourcemtpDurée sur notre Mac
RFC 9106, première recommandation2 GiB141,43 s
RFC 9106, seconde recommandation, pour moins de mémoire64 MiB340,11 s
OWASP, minimum de son résumé19 MiB210,02 s

OWASP liste plusieurs réglages qu'il juge équivalents en défense, comme 46 MiB avec t=1, et 12 MiB avec t=3. Ce sont tous des minimums pour un serveur qui doit connecter beaucoup d'utilisateurs. Une application qui dérive une seule clé sur votre propre appareil peut se permettre bien plus, car l'utilisateur n'attend qu'une fois par déverrouillage.

Une bonne méthode : prenez le maximum de mémoire que chaque appareil pris en charge peut céder, gardez t à 3 ou moins, et vérifiez la durée sur votre appareil le plus lent. N'oubliez pas que si un téléphone manque de mémoire, le déverrouillage échoue.

Essayez

L'outil en ligne de commande argon2 s'installe avec brew install argon2 sur macOS, ou sudo apt install argon2. La mémoire se donne en KiB avec -k. Le sel doit faire au moins 8 caractères. N'utilisez pas de vrais mots de passe de cette façon, car ils peuvent rester dans l'historique du shell :

$ printf 'correct horse battery staple' | argon2 examplesalt12345 -id -t 3 -k 262144 -p 1 -l 32
Type:           Argon2id
Iterations:     3
Memory:         262144 KiB
Parallelism:    1
Hash:           e2c39f45f62dd7bddc5b6eff815f32fae69748a05f4c6f9875dd0e06bb9b2934
Encoded:        $argon2id$v=19$m=262144,t=3,p=1$ZXhhbXBsZXNhbHQxMjM0NQ$4sOfRfYt173cW27/gV8y+uaXSKBfTG+Ydd0OBrubKTQ
0.356 seconds
Verification ok

La chaîne encodée contient tout ce qu'il faut pour vérifier un mot de passe plus tard : la variante, la version (v=19 est la 1.3), les paramètres, le sel et le hachage, ces deux derniers en Base64. Vous pouvez donc augmenter les paramètres plus tard, et les anciens hachages se vérifient toujours.

En Python, avec argon2-cffi dans un environnement virtuel :

from argon2 import PasswordHasher, Type

ph = PasswordHasher(time_cost=3, memory_cost=262144, parallelism=1,
                    hash_len=32, salt_len=16, type=Type.ID)
stored = ph.hash("correct horse battery staple")
ph.verify(stored, "correct horse battery staple")   # True; a wrong password raises VerifyMismatchError
ph.check_needs_rehash(stored)                       # False until you raise the parameters

Il crée un sel aléatoire pour vous. N'écrivez pas votre propre gestion du sel.

Argon2id ou PBKDF2

PBKDF2 répète un hachage de nombreuses fois et ne demande presque aucune mémoire. OWASP demande 600 000 itérations avec HMAC-SHA256, ce qui a pris 0,04 seconde sur notre Mac. C'est une attente acceptable pour vous, mais chaque essai est bon marché à exécuter en parallèle. Utilisez PBKDF2 quand une norme comme FIPS l'exige, et Argon2id sinon.

Un mot de passe faible tombe quand même

Argon2id ralentit chaque essai. Il ne transforme pas un mauvais mot de passe en bon. Les attaquants essaient d'abord les mots de passe courants : un mot de passe proche du haut de leur liste demande très peu d'essais.

La façon dont un coffre combine mot de passe, Argon2id et une clé séparée est expliquée dans ce que veut dire chiffré de bout en bout pour un coffre-fort.

Questions

Quelle variante d'Argon2 choisir ?

Argon2id. La RFC 9106 la recommande par défaut, car elle résiste à la fois aux essais sur GPU et aux attaques par canal auxiliaire.

Que signifie $argon2id$v=19$m=65536,t=3,p=4 ?

Argon2id, version 1.3, 65536 Kio (64 Mio) de mémoire, 3 passes et 4 voies. Le sel et le hash suivent en Base64.

Argon2id est-il meilleur que bcrypt ?

Pour un nouveau système, oui. L'OWASP place Argon2id en premier et garde bcrypt pour l'existant. bcrypt utilise peu de mémoire, toujours la même, et la plupart des implémentations ne lisent que les 72 premiers octets du mot de passe.

Sources

Tous les guides