Le choix entre HS256 et RS256 se résume à une question : qui doit vérifier vos jetons ? HS256 utilise un secret partagé unique pour signer et vérifier, ce qui est simple et rapide, mais signifie que chaque vérificateur détient aussi le pouvoir de créer des jetons. RS256 utilise une clé privée pour signer et une clé publique distincte pour vérifier, vous pouvez donc donner la clé publique à n'importe qui sans lui donner la capacité de falsifier. Maîtrisez cette distinction et le reste de la décision se met en place.
La plupart des comparaisons s'arrêtent à "symétrique versus asymétrique" et vous laissent déterminer ce dont votre système a réellement besoin. Ce guide vous donne une règle de décision liée à votre architecture, les différences réelles au niveau du code, le compromis de performance qui importe rarement, et l'erreur de configuration qui transforme l'un ou l'autre algorithme en une faille de falsification.
HS256 vs RS256 en un coup d'œil#
Ce sont deux algorithmes de signature de jetons JSON Web définis dans la spécification JWA (RFC 7518). Ils protègent la même chose : l'intégrité d'un jeton, afin qu'un serveur puisse être sûr que les revendications qu'il contient (identifiant utilisateur, rôle, expiration) n'ont pas été modifiées. Ils diffèrent entièrement dans la manière dont la clé de signature est structurée.
| Propriété | HS256 | RS256 |
|---|---|---|
| Nom complet | HMAC avec SHA-256 | Signature RSA avec SHA-256 |
| Type de clé | Un secret partagé (symétrique) | Paire de clés privée/publique (asymétrique) |
| Qui peut signer | Toute personne possédant le secret | Seul le détenteur de la clé privée |
| Qui peut vérifier | Toute personne possédant le secret | Toute personne possédant la clé publique |
| Taille du jeton | Signature plus petite | Signature plus grande |
| Vitesse | Très rapide | Signature plus lente, vérification rapide |
| Idéal pour | Un seul service de confiance | Plusieurs vérificateurs, tiers |
Astuce clé : avec HS256, le vérificateur et le signataire utilisent la même clé, donc la capacité de vérification et la capacité de falsification sont indissociables. Avec RS256, elles sont séparées. Ce simple fait détermine presque toutes les décisions architecturales ci-dessous.
Comment fonctionne HS256 (symétrique, secret partagé)#
HS256 signifie HMAC utilisant SHA-256. HMAC est un hachage avec clé : vous fournissez l'en-tête du jeton, la charge utile et une chaîne secrète, et il produit une signature fixe. Pour vérifier, le service récepteur exécute exactement le même HMAC avec exactement le même secret et vérifie que les signatures correspondent.
Comme la signature et la vérification utilisent un seul secret identique, il n'y a pas de notion de côté « public ». Quiconque peut vérifier un jeton peut également en créer un valide. Cela convient lorsqu'un seul service émet des jetons et les vérifie lui-même.
Une configuration HS256 typique en Node ressemble à ceci :
import jwt from "jsonwebtoken";
// Signature
const token = jwt.sign({ sub: "user_123", role: "admin" }, SHARED_SECRET, {
algorithm: "HS256",
expiresIn: "15m",
});
// Vérification (même secret)
const claims = jwt.verify(token, SHARED_SECRET, { algorithms: ["HS256"] });
Le secret doit être une chaîne longue et aléatoire (au moins 32 octets pour SHA-256). Un secret faible ou devinable est la façon la plus courante dont les déploiements HS256 sont compromis, car un attaquant qui récupère le secret peut signer n'importe quoi.
Quand HS256 est le bon choix#
- Un monolithe unique ou un service backend signe et vérifie ses propres jetons.
- Un lien interne de service à service où vous contrôlez entièrement les deux extrémités et pouvez faire tourner un secret partagé en toute sécurité.
- Vous voulez le jeton le plus petit possible et la signature la plus rapide possible, sans avoir besoin d'exposer la vérification à des parties externes.
Comment fonctionne RS256 (asymétrique, paire de clés)#
RS256 est une signature RSA utilisant SHA-256. Vous générez une paire de clés : une clé privée qui signe et une clé publique qui vérifie. La clé privée ne quitte jamais votre serveur d'authentification. La clé publique peut être publiée ouvertement, car la posséder permet à une partie de vérifier les jetons mais jamais de les créer.
Cette séparation est tout l'intérêt. Vous pouvez distribuer la clé publique à une douzaine de microservices, une application mobile ou un partenaire externe, et aucun d'eux ne peut falsifier un jeton même si leur copie de la clé fuit.
import jwt from "jsonwebtoken";
// Signer avec la clé privée (serveur d'authentification uniquement)
const token = jwt.sign({ sub: "user_123", role: "admin" }, PRIVATE_KEY, {
algorithm: "RS256",
expiresIn: "15m",
});
// Vérifier avec la clé publique (n'importe quel service)
const claims = jwt.verify(token, PUBLIC_KEY, { algorithms: ["RS256"] });
La plupart des grands fournisseurs d'identité (Auth0, AWS Cognito, Okta, Google et d'autres utilisant OpenID Connect) émettent des jetons RS256 et publient leurs clés publiques sur un point de terminaison JWKS (une URL .well-known/jwks.json). Vos services récupèrent la clé publique à partir de là et vérifient localement sans jamais contacter le serveur d'authentification par requête.
Avertissement : RS256 ne vous protège que si vous gardez la clé privée secrète et vérifiez avec la clé publique. Un nombre surprenant de bugs proviennent de la configuration accidentelle d'un service pour "vérifier" avec la clé privée, ou d'une mauvaise gestion des formats de clé. En cas de doute, inspectez l'en-tête du jeton pour confirmer que l'
algest celui attendu.
Quand RS256 est le bon choix#
- Microservices : de nombreux services doivent vérifier les jetons mais un seul doit les émettre.
- Vérification par un tiers : un partenaire ou une application cliente doit valider vos jetons sans pouvoir les créer.
- Vous utilisez un fournisseur d'identité externe ou OpenID Connect, où RS256 plus JWKS est la norme.
- Vous souhaitez faire pivoter les clés de signature sans redistribuer un secret à chaque vérificateur (publier une nouvelle clé publique, retirer l'ancienne).
ES256 et la famille d'algorithmes plus large#
HS256 et RS256 sont les deux que vous rencontrerez le plus, mais ce ne sont pas les seules options. ES256 (ECDSA utilisant P-256 et SHA-256) est également asymétrique, comme RS256, mais utilise la cryptographie à courbe elliptique. Il offre le même modèle de signature privée/vérification publique avec des clés et signatures beaucoup plus petites, ce qui maintient les tokens compacts.
| Algorithme | Type | Remarques |
|---|---|---|
| HS256 | Symétrique (HMAC) | Secret partagé, rapide, confiance unique |
| RS256 | Asymétrique (RSA) | Valeur par défaut largement prise en charge pour OIDC, signatures plus grandes |
| ES256 | Asymétrique (ECDSA) | Clés/signatures plus petites, moderne, support de bibliothèque légèrement moins universel |
Si vous avez besoin d'une signature asymétrique et que la taille des tokens ou les performances à grande échelle vous importent, ES256 mérite d'être considéré. Si vous avez besoin d'une compatibilité maximale avec les outils existants et les fournisseurs d'identité, RS256 reste la valeur par défaut la plus sûre. La logique de décision entre ES256 et RS256 est la même qu'entre RS256 et HS256, avec en plus une vérification de compatibilité de vos bibliothèques.
La règle de décision : qui vérifie vos jetons ?#
C'est la partie que la plupart des articles omettent. Oubliez la vitesse et la longueur de clé un instant et répondez à une question : combien de parties distinctes vérifient vos jetons, et faites-vous confiance à toutes pour également pouvoir signer ?
Utilisez HS256 si chaque vérificateur est aussi un signataire de confiance#
Si la seule chose qui vérifie vos jetons est le même service (ou un petit ensemble de services internes entièrement fiables) qui les émet, le modèle à secret partagé est plus simple et plus rapide. Il n'y a pas de problème de distribution de clé car il y a un seul secret et vous contrôlez partout où il réside. Un monolithe classique avec un seul backend est le cas d'école pour HS256.
Utilisez RS256 (ou ES256) dès que la vérification se disperse#
Dès qu'un jeton doit être vérifié par quelque chose à qui vous ne voulez pas donner la capacité de signer, vous avez besoin de clés asymétriques. Exemples :
- Un frontend ou un client mobile vérifiant la validité d'un jeton.
- Une flotte de microservices, où compromettre un vérificateur ne doit pas permettre à un attaquant de forger des jetons pour l'ensemble du système.
- Un consommateur d'API externe ou un partenaire qui doit faire confiance aux jetons que vous émettez.
- Tout flux OpenID Connect / OAuth avec un fournisseur d'identité externe.
La règle en une phrase : si l'ensemble des vérificateurs est plus grand que l'ensemble des parties en qui vous avez confiance pour signer, utilisez RS256. Avec un secret partagé, chaque vérificateur est un faussaire potentiel, et ce risque augmente avec chaque service détenant le secret.
Performances : réelles, mais rarement décisives#
HMAC (HS256) est nettement plus rapide que RSA (RS256) pour l'étape de signature, souvent d'un ordre de grandeur dans les benchmarks bruts. La vérification RSA est raisonnablement rapide, mais la signature RSA est l'opération coûteuse. Donc, si vous signez d'énormes volumes de jetons sur une seule machine, HS256 gagne en termes de CPU.
Pour la plupart des applications, cette différence est négligeable. Vous signez généralement un jeton une fois lors de la connexion et le vérifiez plusieurs fois sur sa courte durée de vie. La vérification avec RS256 est suffisamment rapide pour que le coût par requête soit négligeable par rapport à une requête de base de données ou un saut réseau. Choisissez votre algorithme en fonction du modèle de confiance en premier lieu, et ne laissez les performances départager qu'en cas d'extrême échelle de signature.
Astuce : la taille du jeton est une préoccupation plus pratique que le CPU. Les signatures RS256 sont plus grandes, ce qui gonfle chaque requête transportant le jeton dans un en-tête. Si vous êtes sensible à la bande passante et avez besoin de clés asymétriques, ES256 produit des jetons nettement plus petits que RS256.
L'erreur qui casse tout : faire confiance au champ alg#
Quel que soit l'algorithme choisi, l'erreur de configuration la plus dangereuse est de laisser le jeton décider lui-même de la façon dont il est vérifié. Un JWT contient un champ alg dans son en-tête, et un code de vérification naïf lit ce champ et vérifie en conséquence. Les attaquants exploitent cela de deux manières bien connues.
Premièrement, l'astuce alg: none : un attaquant définit l'algorithme sur none, supprime la signature, et certaines bibliothèques acceptent joyeusement le jeton non signé comme valide. Deuxièmement, l'attaque de confusion RS256 vers HS256 : un serveur configuré pour RS256 publie sa clé publique, un attaquant modifie l'en-tête en HS256, et signe un jeton falsifié en utilisant cette clé publique comme s'il s'agissait d'un secret HMAC. Si le serveur vérifie ensuite HS256 avec la clé publique qu'il connaît, le jeton falsifié passe.
La solution est la même dans les deux cas et tient en une ligne d'intention : épingler l'algorithme accepté sur le vérificateur. Ne laissez jamais le jeton choisir.
// Bien : le serveur dicte l'algorithme, pas le jeton
jwt.verify(token, PUBLIC_KEY, { algorithms: ["RS256"] });
Transmettez toujours une liste explicite d'algorithmes autorisés à votre appel de vérification et assurez-vous qu'elle n'inclut pas none. Ne mélangez pas HS256 et RS256 sur le même chemin de vérification, car cette ambiguïté est exactement ce dont l'attaque de confusion a besoin. Si vous voulez comprendre pourquoi le simple décodage d'un jeton ne vous dit rien sur son authenticité, notre guide sur le décodage par rapport à la vérification d'un JWT explique la différence qui piège de nombreux développeurs.
Lorsque vous déboguez un jeton avec l'un ou l'autre algorithme, collez-le dans notre décodeur JWT gratuit pour lire l'en-tête et confirmer la valeur alg, l'expiration et les revendications avant de lui faire confiance. Voir l'en-tête réel est le moyen le plus rapide de détecter un algorithme non conforme ou falsifié.
Gestion des clés : la différence pratique au quotidien#
Le choix de l'algorithme détermine discrètement la charge de travail de gestion des clés.
Avec HS256, vous avez un seul secret. Facile à stocker, mais sa rotation implique de mettre à jour simultanément tous les endroits qui le détiennent, et une fuite, où que ce soit, compromet tout. Conservez-le dans un gestionnaire de secrets, jamais dans le contrôle de source, et traitez tout service qui le détient comme faisant partie de votre noyau de confiance.
Avec RS256, vous gérez une paire de clés. La rotation est plus douce : publiez une nouvelle clé publique (souvent via un point de terminaison JWKS avec un identifiant de clé), commencez à signer avec la nouvelle clé privée, et retirez l'ancienne clé une fois que les jetons en circulation expirent. Les vérificateurs récupèrent automatiquement la nouvelle clé publique. La contrepartie est plus de complexité initiale, c'est pourquoi un petit service unique en a rarement besoin.
Pour un tour d'horizon plus large de la gestion sécurisée des jetons, y compris le stockage, l'expiration et les vérifications à effectuer, consultez notre guide sur le décodeur JWT et la sécurité des jetons.
HS256 vs RS256 : l'essentiel#
Le choix entre HS256 et RS256 ne repose pas vraiment sur la force cryptographique, car les deux sont sécurisés s'ils sont correctement configurés. Il s'agit plutôt de limites de confiance. Utilisez HS256 lorsqu'un seul service de confiance signe et vérifie ses propres jetons, et que vous recherchez simplicité et rapidité. Optez pour RS256 (ou ES256 pour des jetons plus petits) dès que plusieurs parties doivent vérifier sans que vous ayez confiance en leur capacité de signature, ce qui décrit presque toutes les configurations de microservices, applications mobiles, tiers et OpenID Connect.
Quel que soit votre choix, verrouillez l'algorithme côté vérificateur avec une liste d'autorisation explicite, n'acceptez jamais none, et ne vérifiez jamais les jetons d'un algorithme avec la clé d'un autre. En cas de doute, décodez le jeton et lisez son en-tête pour savoir exactement à quoi vous avez affaire.
Foire aux questions#
RS256 est-il plus sûr que HS256 ? Pas intrinsèquement. Les deux sont cryptographiquement solides s'ils sont correctement configurés. RS256 est plus sûr pour les systèmes distribués car la clé de vérification publique ne peut pas être utilisée pour forger des jetons, donc la divulguer à de nombreux vérificateurs présente un faible risque. HS256 concentre tout le pouvoir dans un secret partagé unique, ce qui est acceptable pour un seul service de confiance mais plus risqué à mesure que le nombre de détenteurs du secret augmente.
Puis-je passer de HS256 à RS256 plus tard ? Oui, mais prévoyez une période de transition. Vous générerez une paire de clés, commencerez à signer les nouveaux jetons avec la clé privée RS256 et mettrez à jour les vérificateurs pour accepter RS256. Évitez de configurer un service pour accepter les deux algorithmes à la fois, car cette ambiguïté permet l'attaque par confusion d'algorithme. Migrez proprement et retirez la vérification HS256 une fois que les anciens jetons ont expiré.
Quel algorithme utilisent les fournisseurs d'identité comme Auth0 et Cognito ?
La plupart des grands fournisseurs d'identité utilisent RS256 par défaut et publient leurs clés publiques sur un point de terminaison JWKS (une URL .well-known/jwks.json). Vos services récupèrent la clé publique et vérifient les jetons localement. C'est pourquoi RS256 est le choix pratique par défaut pour toute intégration OpenID Connect ou OAuth avec un fournisseur externe.
Pourquoi RS256 est-il plus lent que HS256 ? La signature RSA est mathématiquement plus lourde que l'opération HMAC utilisée par HS256, donc la signature est nettement plus lente, souvent d'un ordre de grandeur dans les benchmarks bruts. La vérification est rapide pour les deux. Pour la plupart des applications, cet écart n'a pas d'importance car vous vérifiez beaucoup plus souvent que vous ne signez, et le coût de vérification est faible par rapport au temps réseau et base de données.
Qu'est-ce que l'attaque par confusion d'algorithme ?
C'est une exploitation où un serveur s'attendant à RS256 est trompé en vérifiant un jeton HS256 en utilisant sa propre clé publique comme secret HMAC. Comme la clé publique est, par conception, connue des attaquants, ils peuvent forger un jeton valide. La solution est de verrouiller l'algorithme accepté sur le vérificateur avec une liste blanche et de ne jamais laisser l'en-tête alg du jeton décider. Vous pouvez confirmer l'algorithme déclaré d'un jeton avec un décodeur JWT gratuit lors du débogage.
Devrais-je utiliser ES256 au lieu de RS256 ? Envisagez ES256 lorsque vous avez besoin d'une signature asymétrique mais souhaitez des jetons et des clés plus petits, ce qui améliore la bande passante et les clients mobiles. Il utilise le même modèle de signature privée et vérification publique que RS256. Le principal inconvénient est un support légèrement moins universel des bibliothèques et des fournisseurs, donc vérifiez que votre pile prend en charge ES256 avant de vous engager.



