Le choix de l'algorithme qui définit la sécurité de votre JWT
Chaque fois qu'un serveur crée un JWT, il doit prendre une décision critique : quel algorithme doit signer ce jeton ?
Les deux choix les plus courants sont HS256 (symétrique) et RS256 (asymétrique). La plupart des développeurs en choisissent un sans comprendre pleinement les enjeux. Ce choix affecte tout — de la manière dont vos secrets sont gérés à la vulnérabilité de votre système face à des attaques spécifiques.
Ce guide détaille les deux algorithmes, explique quand utiliser chacun d'eux et montre les risques de sécurité en cas de mauvais choix.
Ce que fait réellement HS256
HS256 signifie HMAC-SHA256. C'est un algorithme symétrique, ce qui signifie que la même clé secrète est utilisée pour signer et vérifier le jeton.
Le serveur signe le jeton : HMAC-SHA256(header + payload, SECRET_KEY)
Le serveur vérifie le jeton : HMAC-SHA256(header + payload, SECRET_KEY)
La même clé effectue les deux tâches.
Quand HS256 fonctionne bien
- Applications à serveur unique où un seul service signe et vérifie les jetons.
- Microservices internes où tous les services sont approuvés et partagent le même secret.
- Flux d'authentification simples où la distribution des clés n'est pas un problème.
Le risque de HS256
Si la clé secrète est faible, courte ou prévisible, elle peut être forcée par brute-force. Un GPU moderne utilisant Hashcat peut tester des milliards de combinaisons HMAC-SHA256 par seconde.
Benchmarks réels :
| Longueur de clé | Type de clé | Temps de cassage (RTX 4090) | |---|---|---| | 6 caractères | minuscules | moins d'une seconde | | 8 caractères | casse mixte | moins d'une heure | | 12 caractères | aléatoire | ~200 ans | | 32 octets | aléatoire | mort thermique de l'univers |
Toute la sécurité de HS256 dépend d'une seule chose : la force de votre clé secrète.
Si vous utilisez HS256, votre secret doit comporter au moins 256 bits (32 octets) de données aléatoires cryptographiques. Générez-le comme ceci :
openssl rand -base64 32
N'utilisez jamais de chaînes lisibles par l'homme comme "secret", "password123" ou "my-jwt-key".
Ce que fait réellement RS256
RS256 signifie RSA-SHA256. C'est un algorithme asymétrique, ce qui signifie qu'il utilise deux clés différentes :
- Une clé privée pour signer le jeton (gardée secrète sur le serveur d'authentification).
- Une clé publique pour vérifier le jeton (peut être partagée avec n'importe qui).
Le serveur d'authentification signe : RSA-SHA256(header + payload, PRIVATE_KEY)
N'importe quel service vérifie : RSA-SHA256(header + payload, PUBLIC_KEY)
Quand RS256 fonctionne bien
- Systèmes distribués où plusieurs services doivent vérifier les jetons mais un seul service doit les créer.
- Intégrations tierces où vous voulez que des services externes vérifient les jetons sans partager votre secret de signature.
- API publiques où la vérification des jetons doit se faire sans exposer de clés sensibles.
- Flux OAuth / OpenID Connect où les fournisseurs d'identité publient des clés publiques via des points de terminaison JWKS.
L'avantage de RS256
Même si quelqu'un possède la clé publique (qui est conçue pour être publique), il ne peut pas forger de jetons. Seule la clé privée peut signer. Cela élimine toute une classe d'attaques.
La différence critique
HS256 (Symétrique) :
Signature : CLÉ_SECRÈTE
Vérification : CLÉ_SECRÈTE ← même clé
Risque : Quiconque possède la clé peut signer ET vérifier
RS256 (Asymétrique) :
Signature : CLÉ_PRIVÉE ← secrète
Vérification : CLÉ_PUBLIQUE ← publique
Risque : Seul le détenteur de la clé privée peut signer
Avec HS256, chaque service capable de vérifier les jetons peut également forger des jetons. Si un service est compromis, l'attaquant peut créer des jetons pour n'importe quel utilisateur.
Avec RS256, même si un service de vérification est compromis, l'attaquant ne peut pas forger de jetons car il ne possède pas la clé privée.
L'attaque par confusion d'algorithme
C'est là que le choix entre HS256 et RS256 devient une réelle vulnérabilité de sécurité.
Si un serveur accepte à la fois HS256 et RS256, un attaquant peut :
- Prendre un jeton légitime signé avec RS256.
- Modifier l'en-tête pour indiquer
"alg": "HS256". - Signer le jeton modifié en utilisant la clé publique comme secret HMAC.
- L'envoyer au serveur.
Le serveur voit alg: HS256 et pense : "Je dois vérifier avec le secret partagé." Il récupère la clé qu'il a dans ses fichiers — qui est la clé publique. L'attaquant a signé avec la clé publique. Les signatures correspondent. Le jeton forgé est accepté.
Il s'agit d'une vulnérabilité réelle documentée dans le CVE-2016-10555 affectant la bibliothèque npm populaire jsonwebtoken.
Comment l'empêcher
Ne laissez jamais l'en-tête du jeton décider quel algorithme utiliser.
Votre serveur doit imposer un algorithme spécifique :
// Exemple Node.js
jwt.verify(token, publicKey, { algorithms: ['RS256'] });
Codez l'algorithme en dur. Mettez-en exactement un sur liste blanche. Ignorez tout ce que dit l'en-tête du jeton.
Lequel devriez-vous utiliser ?
Utilisez HS256 si :
- Vous avez un serveur unique ou un petit cluster de confiance.
- Tous les services qui vérifient les jetons sont sous votre contrôle direct.
- Vous pouvez garantir que votre clé secrète est forte (aléatoire 256 bits).
- Vous voulez une gestion des clés plus simple.
- La performance est cruciale (HS256 est plus rapide que RS256).
Utilisez RS256 si :
- Plusieurs services doivent vérifier les jetons.
- Vous avez des services tiers ou des API externes.
- Vous utilisez OAuth ou OpenID Connect.
- Vous souhaitez publier des clés de vérification sans risque de sécurité.
- Vous devez renouveler les clés sans coordination entre tous les services.
- La sécurité est plus importante que la performance.
La règle générale
Petite application interne → HS256 avec un secret fort
Tout ce qui est distribué ou exposé au public → RS256
Si vous n'êtes pas sûr, choisissez RS256. Il est plus difficile de faire une erreur de configuration fatale.
Inspecter l'algorithme de votre JWT en toute sécurité
Lors du débogage des JWT, vous devez vérifier quel algorithme a été utilisé. L'algorithme se trouve dans l'en-tête du jeton.
Ne collez jamais de jetons dans des décodeurs JWT en ligne. Votre jeton contient des identifiants d'authentification. Si le jeton est toujours actif, vous donnez une clé en direct à un serveur tiers.
Utilisez un décodeur local côté client qui traite tout dans votre navigateur sans envoyer de données nulle part.
Essayez le Décodeur JWT de FmtDev — tout fonctionne localement. Votre jeton ne quitte jamais votre machine.
Liste de contrôle de sécurité
Quel que soit l'algorithme choisi :
- Imposez l'algorithme côté serveur — ne faites jamais confiance à l'en-tête du jeton.
- Utilisez des clés fortes — 256 bits aléatoires pour HS256, 2048 bits minimum pour RS256.
- Définissez des délais d'expiration courts — minutes ou heures, pas jours.
- Ne stockez jamais de données sensibles dans le payload — il n'est pas chiffré.
- Validez tous les claims — vérifiez
exp,iss,audà chaque requête. - Renouvelez les clés périodiquement — surtout si un service est compromis.
- Décodez les jetons localement — n'utilisez jamais d'outils en ligne pour des jetons actifs.