Accueil
  • #sécurité
  • #JWT
  • #outils

Lire un JWT : en-tête, charge utile et signature

Par · · 4 min de lecture

Dans l’en-tête d’une requête d’API, on croise souvent une longue chaîne qui commence par eyJ : un JWT (JSON Web Token). Elle ressemble à du bruit, pourtant deux de ses trois parties se lisent à l’œil nu une fois décodées. Savoir les lire aide à comprendre pourquoi un jeton est refusé ou à repérer une erreur de date.

Voici l’anatomie d’un JWT, ses revendications courantes, et surtout ce qu’un décodage ne prouve pas.

Les trois parties d’un JWT#

Un JWT est composé de trois segments séparés par des points :

en-tête.charge-utile.signature

Les deux premiers sont du JSON encodé en Base64URL, la variante du Base64 qui remplace + et / par - et _ et omet le = final. Exemple de contenu décodé :

{"alg":"HS256","typ":"JWT"}
{"sub":"1234567890","name":"John Doe","iat":1516239022}
  • L’en-tête décrit le jeton : algorithme de signature (alg), type (typ) et parfois identifiant de la clé (kid).
  • La charge utile (payload) contient les revendications : informations sur l’utilisateur et sur la validité du jeton.
  • La signature est calculée par le serveur à partir des deux premiers segments et d’une clé secrète (HS256) ou privée (RS256, ES256). Elle sert à détecter toute modification.

Le principe de la signature, pour HS256 :

HMAC-SHA256( base64url(en-tête) + "." + base64url(charge utile), clé secrète )

Les revendications courantes#

La norme (RFC 7519) définit quelques noms standard :

  • iss : l’émetteur du jeton.
  • sub : le sujet, en général l’identifiant de l’utilisateur.
  • aud : l’audience, le service destinataire.
  • exp : l’instant d’expiration.
  • nbf : l’instant avant lequel le jeton n’est pas valide.
  • iat : l’instant d’émission.
  • jti : un identifiant unique du jeton.

Les trois dates sont en secondes écoulées depuis le 1er janvier 1970 (UTC), pas en millisecondes. Erreur classique : Date.now() renvoie des millisecondes en JavaScript, il faut diviser par 1000. Pour convertir 1516239022 en date lisible, utilisez un convertisseur de timestamp.

Décoder n’est pas vérifier#

Le contenu d’un JWT est encodé, pas chiffré : n’importe qui peut le lire, et n’importe qui peut en fabriquer un avec le contenu de son choix. Décoder un jeton ne dit rien de son authenticité. Seul un serveur qui détient la clé peut vérifier la signature, puis contrôler exp, iss et aud.

Deux conséquences :

  • Ne mettez ni secret ni donnée sensible dans la charge utile (mot de passe, numéro de carte). Les jetons chiffrés (JWE) existent, mais ils ont cinq segments et ne se lisent pas sans clé.
  • Un jeton avec "alg":"none" n’a pas de signature. Un serveur ne doit jamais l’accepter comme preuve d’identité.

Décoder un segment, c’est du simple Base64URL : l’outil Base64 le lit aussi, et l’article Base64, pas du chiffrement explique pourquoi cet encodage ne protège rien.

Ne collez pas un token de production sur un site tiers#

Un jeton valide est un laissez-passer : tant qu’il n’a pas expiré, celui qui le possède peut agir au nom de son titulaire. Le coller dans un décodeur en ligne dont vous ignorez le fonctionnement, c’est risquer qu’il soit transmis ou journalisé. Quelques réflexes :

  • Utilisez un décodeur qui travaille dans le navigateur, sans envoi.
  • Préférez un jeton de test ou déjà expiré quand c’est possible.
  • Ne publiez jamais un jeton dans un ticket, une capture d’écran ou une discussion.
  • Si un jeton actif a fuité, révoquez-le.

Lire un JWT avec l’outil#

Le décodeur JWT travaille dans votre navigateur, sans envoyer le jeton :

  1. Collez le jeton dans « Jeton JWT » (le préfixe Bearer, les guillemets et les retours à la ligne sont ignorés), ou cliquez sur « Utiliser un exemple ».
  2. Consultez l’en-tête (algorithme, type, kid) et la charge utile en JSON lisible.
  3. Dans le tableau des revendications, les dates exp, nbf et iat sont converties en français avec leur état : « Encore valide pendant… » ou « Expiré il y a… », mis à jour toutes les 15 secondes.
  4. La signature est affichée telle quelle, avec la mention « non vérifiée ».

L’outil signale un jeton non signé (alg égal à none) et explique les erreurs : mauvais nombre de segments, caractères invalides, JSON incorrect. Un jeton à cinq segments est reconnu comme un JWE.

En résumé#

Un JWT, c’est un en-tête, une charge utile et une signature, les deux premiers lisibles par tous. Le décodage montre ce que contient le jeton, jamais s’il est authentique : vérifiez la signature côté serveur, gardez les secrets hors de la charge utile et décodez vos jetons réels dans un outil local.

Outils utilisés dans cet article

À lire aussi