Vérifier la signature d'un JSON Web Token (JWT)
- Tableau de bord
- Documentation
- API
Pourquoi vérifier la signature d'un JWT ?
Un JSON Web Token (JWT) se décompose en trois parties séparées par des points :
header.payload.signature. Décoder un JWT consiste simplement à lire les deux premières
parties (qui sont du Base64URL). N'importe qui peut le faire, et n'importe qui peut fabriquer
un JWT avec le payload de son choix. Ce qui rend un JWT digne de confiance, c'est uniquement la
signature : sans vérification, accepter un JWT revient à laisser entrer chez vous toute personne qui
prétend être quelqu'un, sans demander de pièce d'identité.
Cet outil vérifie la signature d'un JWT à partir d'une clé. Il ne se contente pas de décoder : il recalcule la signature à partir du header, du payload et de votre clé, puis la compare avec la signature du token. Si les deux concordent, le token est authentique. Sinon, il a été forgé, modifié, ou signé avec une autre clé.
La vérification est la pierre angulaire de toute architecture qui utilise des JWT pour
l'authentification ou l'autorisation : sans signature valide, le payload peut mentir.
Un attaquant qui modifierait "role":"user" en "role":"admin" n'aurait aucune
difficulté à le faire si le serveur ne vérifiait que le format du token et pas sa signature.
Algorithmes courants
La spécification JWT (RFC 7518, JSON Web Algorithms) définit plusieurs familles d'algorithmes. Voici les plus utilisées en production :
- HMAC (HS256, HS384, HS512) : signature symétrique à base de HMAC-SHA. La même clé secrète sert à signer et à vérifier. Simple à mettre en place, performant, mais toute partie capable de vérifier le token est aussi capable d'en émettre. Adapté aux scénarios où l'émetteur et le vérificateur sont la même équipe ou le même service.
- RSA (RS256, RS384, RS512) : signature asymétrique. La clé privée signe, la clé publique vérifie. Idéal lorsque l'émetteur et les vérificateurs sont des entités distinctes (OAuth2, OpenID Connect, fédération d'identité). C'est l'algorithme privilégié par la plupart des fournisseurs d'identité publics.
- ECDSA (ES256, ES384) : signature asymétrique sur courbes elliptiques. Même logique que RSA (clé privée pour signer, clé publique pour vérifier) mais avec des clés et signatures plus compactes pour un niveau de sécurité équivalent. De plus en plus répandu dans les architectures modernes.
Comment fournir la clé
Le format de la clé attendue dépend de l'algorithme déclaré dans le header du JWT :
- HS256, HS384, HS512 : la clé est une chaîne secrète (string).
C'est le secret partagé avec l'émetteur, souvent stocké dans une variable d'environnement comme
JWT_SECRET. Aucune mise en forme particulière, juste la valeur brute. - RS256, RS384, RS512 : la clé est une clé publique RSA au format PEM,
qui commence par
-----BEGIN PUBLIC KEY-----et se termine par-----END PUBLIC KEY-----. Conservez les retours à la ligne tels quels, sinon OpenSSL refuse de la parser. - ES256, ES384 : la clé est une clé publique ECDSA au format PEM, sur la courbe correspondante (P-256 pour ES256, P-384 pour ES384).
Exemple de clé publique RSA attendue
-----BEGIN PUBLIC KEY-----
MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEAxe...
...vQIDAQAB
-----END PUBLIC KEY-----
Comment fonctionne la vérification ?
Notre serveur reproduit exactement l'opération qu'a faite l'émetteur :
- Il sépare le JWT en header, payload et signature.
- Il concatène
base64url(header) + "." + base64url(payload). - Pour HMAC, il calcule un HMAC-SHA-256/384/512 avec votre clé secrète, puis compare avec la
signature reçue via
hash_equals(comparaison à temps constant pour éviter les attaques temporelles). - Pour RSA, il appelle
openssl_verifyavec votre clé publique au format PEM.
Cas d'usage
- Debug d'authentification API : vous recevez un 401, vérifiez si votre token est bien signé avec la clé attendue.
- Validation d'un token reçu d'un fournisseur : un partenaire (Auth0, Keycloak, Cognito, Okta) vous envoie des JWT signés en RS256 ; vous voulez confirmer qu'ils proviennent bien de lui avec sa clé publique.
- Audit de sécurité : vérifier qu'un service tiers signe correctement ses tokens avec un algorithme robuste, et pas en HS256 avec un secret faible.
- Tests manuels : vérifier qu'un JWT généré par votre code passe bien la vérification avec la clé publique fournie.
- Vérification rapide d'un token reçu : pendant l'intégration d'un SSO ou d'une API partenaire, vérifier en quelques secondes que la chaîne signature/clé fonctionne avant d'écrire la moindre ligne de code.
Comment utiliser l'outil
- Collez le JWT complet (les trois parties séparées par des points).
- Indiquez la clé adaptée à l'algorithme du header :
- Pour HS256, HS384 ou HS512, la clé est la chaîne secrète
partagée avec l'émetteur. C'est une chaîne libre, souvent stockée dans une
variable d'environnement comme
JWT_SECRET. - Pour RS256, RS384 ou RS512, la clé est la clé publique au format
PEM, qui commence par
-----BEGIN PUBLIC KEY-----et se termine par-----END PUBLIC KEY-----.
- Pour HS256, HS384 ou HS512, la clé est la chaîne secrète
partagée avec l'émetteur. C'est une chaîne libre, souvent stockée dans une
variable d'environnement comme
- Lancez la vérification. L'outil affiche le statut (valide ou invalide) et le payload décodé.
Pièges courants à éviter
- Algorithme "none" : la spec autorise
alg: none, qui signifie "pas de signature". Une faille classique consiste à fabriquer un token avec ce header en espérant que le serveur l'accepte. Notre outil rejette systématiquement les tokens avecalg: none. - Confusion HMAC vs RSA (algorithm confusion) : un attaquant change l'algorithme
RS256enHS256et signe le payload avec la clé publique RSA utilisée comme secret HMAC. Si le serveur ne contrôle pas l'algorithme, il accepte le token. Toujours verrouiller l'algorithme attendu côté serveur. - Secrets HMAC en dur dans le code : un secret committé dans un dépôt Git rend toute la confiance des tokens caduque. Stockez les secrets dans des variables d'environnement ou un coffre-fort applicatif.
- Clé publique vs clé privée : pour vérifier un JWT signé en RSA ou ECDSA, on fournit la clé publique, jamais la privée. La privée ne sert qu'à signer et ne doit jamais sortir de l'émetteur.
- Expiration ignorée : une signature valide sur un token expiré ne doit
jamais être acceptée. Pensez à vérifier
expetnbf. - Audience non contrôlée : un token destiné à l'API A ne devrait pas être accepté
par l'API B. Vérifiez le claim
aud.
Claims temporels : exp et nbf
Au-delà de la signature, un JWT valide doit aussi respecter ses contraintes temporelles :
- exp (expiration) : le token n'est plus valide après cette date.
- nbf (not before) : le token n'est pas encore valide avant cette date.
Notre outil signale explicitement quand un token est expiré ou pas encore valide, même si sa signature est correcte. C'est important : une signature valide sur un token expiré ne doit jamais être acceptée en production.
Différence avec notre JWT decoder
Notre JWT decoder se contente de décoder les parties header et payload pour les rendre lisibles. Il n'effectue aucune vérification de signature et ne demande pas de clé. Utilisez-le pour inspecter rapidement le contenu d'un token. Utilisez le JWT verifier (cette page) dès que vous avez besoin de prouver qu'un token est authentique. Pour fabriquer un JWT signé à des fins de test, utilisez notre JWT builder.
Questions fréquentes
Pourquoi RS256 plutôt que HS256 ?
Avec HS256, l'émetteur et le vérificateur partagent le même secret : tout vérificateur peut donc émettre des tokens. C'est gérable quand on contrôle les deux bouts. Dès qu'on parle d'un fournisseur d'identité unique avec plusieurs services consommateurs, on bascule en RS256 : l'émetteur garde la clé privée, on distribue la clé publique à toutes les API qui doivent vérifier. Aucune API consommatrice ne peut alors forger de tokens.
Comment récupérer la clé publique d'un fournisseur d'identité (IdP) ?
La plupart des IdP exposent un endpoint JWKS standardisé (par exemple
https://exemple.com/.well-known/jwks.json). Cet endpoint renvoie un JSON contenant
les clés publiques actives. Vous pouvez convertir l'entrée JWK qui correspond au kid
du header de votre JWT en clé PEM via la commande openssl ou via une bibliothèque
JWKS de votre stack (par exemple jose-jwt, jwks-rsa).
Que faire si le verify échoue ?
Vérifiez d'abord l'algorithme : un token signé en HS256 ne se vérifie pas avec une clé RSA, et
inversement. Vérifiez ensuite la clé : un caractère blanc en trop, un retour à la ligne manquant
dans une clé PEM, ou un secret HMAC légèrement différent de celui utilisé par l'émetteur
suffisent à faire échouer la vérification. Si l'IdP a effectué une rotation de clé, votre
kid peut pointer vers une clé que vous n'avez plus.
JWKS, c'est quoi ?
JWKS (JSON Web Key Set, RFC 7517) est un format JSON qui décrit un ensemble de
clés publiques. Chaque clé est identifiée par un kid (key ID) et le JWT à vérifier
référence ce kid dans son header. Le mécanisme permet à l'IdP de faire tourner ses
clés sans casser les vérificateurs : ils interrogent simplement l'endpoint JWKS pour récupérer la
clé correspondant au kid du token reçu.
Comment générer une paire de clés RSA pour signer mes JWT ?
Avec OpenSSL : openssl genrsa -out private.pem 2048 puis
openssl rsa -in private.pem -pubout -out public.pem. La clé privée signe côté
émetteur, la clé publique vérifie côté consommateur. Pour de nouveaux services, préférez 3072 ou
4096 bits.
Faut-il chiffrer le JWT en plus de le signer (JWE) ?
Un JWT signé (JWS) garantit l'intégrité et l'authenticité, mais le payload reste lisible par quiconque le récupère. Si le token contient des données sensibles (identifiants internes, droits détaillés, données personnelles), envisagez le format JWE (JSON Web Encryption) qui chiffre le payload en plus de le signer.
Exemple de requête
curl -X POST https://cdrn.fr/api/v1/tools/jwt-verifier/execute \
-H "Content-Type: application/json" \
-d '{"token":"...","key":"..."}'
Schéma d'entrée
| Champ | Type | Requis | Défaut |
|---|---|---|---|
token |
text | ✓ | – |
key |
text | ✓ | – |
Points d'accès
GET https://cdrn.fr/api/v1/tools- liste tous les outils disponiblesGET https://cdrn.fr/api/v1/tools/jwt-verifier- récupère le schéma de cet outilPOST https://cdrn.fr/api/v1/tools/jwt-verifier/execute- exécute cet outil avec un payload JSON