Définition
Les JWT / JWS / JWE forment une famille de standards IETF (RFC 7515 à 7519, 2015) qui définit un format compact, URL-safe et portable pour transporter des claims (assertions) signées et/ou chiffrées au format JSON.
C'est la brique fondamentale de l'authentification moderne (access tokens OAuth, ID Tokens OIDC), de la signature applicative et du transport sécurisé de données structurées (webhooks signés, attestations).
| Standard | RFC | Rôle |
|---|---|---|
| JWT | 7519 | Format général (claims JSON encodés) |
| JWS | 7515 | Signature (intégrité, authenticité) |
| JWE | 7516 | Chiffrement (confidentialité) |
| JWA | 7518 | Algorithmes (HS256, RS256, A256GCM…) |
| JWK | 7517 | Représentation des clés en JSON |
Format JWT (signé = JWS)
Trois parties séparées par des points :
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.
eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkFsaWNlIiwiaWF0IjoxNzE0MDAwMDAwfQ
.
SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c- Header (base64url) :
{"alg":"HS256","typ":"JWT"} - Payload (base64url) :
{"sub":"1234567890","name":"Alice","iat":1714000000} - Signature : HMAC ou RSA/ECDSA selon
alg
Les claims standards : iss (émetteur), sub (sujet), aud (destinataire), exp (expiration), nbf (not before), iat (issued at), jti (identifiant unique anti-replay), plus des claims privés (email, roles, scope).
Algorithmes de signature (JWS)
| Algo | Type | Usage typique |
|---|---|---|
HS256 | HMAC symétrique | Tests, monolithes |
RS256 | RSA asymétrique | OAuth, OIDC classique |
PS256 | RSA-PSS | Recommandé FAPI (Open Banking) |
ES256 | ECDSA P-256 | Recommandé FAPI, mobile |
EdDSA | Ed25519 | Moderne, rapide |
none | Aucune signature | Interdit (faille historique) |
Bonnes pratiques : préférer l'asymétrique (clé publique partageable) pour les API publiques, privilégier PS256/ES256, ne jamais accepter alg: none, et toujours vérifier l'alg attendu côté serveur plutôt que de faire confiance à l'header.
JWE (chiffrement)
JWE chiffre le payload (confidentialité) en plus de l'intégrité, en 5 parties : header.encrypted_key.iv.ciphertext.tag. Key encryption courant : RSA-OAEP, ECDH-ES, A256KW ; content encryption : A256GCM, A128CBC-HS256. Usage : transport de données secrètes (carte tokenisée, données KYC) entre services.
JWT vs session traditionnelle
| Aspect | Session cookie | JWT |
|---|---|---|
| State | Serveur | Client (stateless) |
| Scaling | Sticky session ou DB partagée | Trivial |
| Révocation | Suppression server-side | Difficile (blacklist) |
| Lisibilité | Opaque | Lisible (base64url) |
| Risque vol | Cookie httpOnly | Bearer = porteur |
Cas d'usage
- OAuth / OIDC : access token (souvent JWT, FAPI exige un JWT signé bindé), ID Token (toujours JWT signé), Request Object JAR (JWT signé).
- API : bearer JWT dans
Authorization, vérifié via clé publique (JWKS endpoint). - Webhooks : Stripe, GitHub, Slack signent en JWS.
- Identité / KYC : Verifiable Credentials W3C, et SD-JWT (disclosure sélective) pour l'EUDI Wallet.
- eIDAS : JAdES, profil de signature qualifiée basé sur JWS.
Attaques connues
alg: none: certaines vieilles librairies acceptaient un payload non vérifié.- Confusion d'algo (HS256 vs RS256) : signer avec la clé publique RSA comme secret HMAC, si le serveur ne fige pas l'
alg. - Injection
kid: unkidmal validé peut ouvrir une SQL injection ou un path traversal. - Replay : un JWT volé reste valide jusqu'à
exp(mitigation :jti+ cache, tokens courts). - Fuite d'info : le payload est lisible — n'y mettre aucune donnée sensible, chiffrer en JWE si besoin.
Bonnes pratiques
Préférer PS256/ES256, des tokens courts (5-15 min, refresh long), des tokens bindés au client (mTLS, DPoP) en FAPI ; vérifier systématiquement iss, aud, exp, nbf et alg ; faire tourner les clés (JWKS) ; éviter les PII en clair (JWE si nécessaire) ; auditer régulièrement les dépendances (CVE).
Ce que JWT / JWS / JWE n'est pas
- Pas un chiffrement de transport : c'est applicatif, TLS reste requis.
- Pas une session : un token, généralement court et stateless.
- Pas un mot de passe : un token d'accès émis après authentification.
- Pas révocable nativement : valide jusqu'à expiration, sauf blacklist maintenue.
Dans l'écosystème PSD2 / Open Finance
JWT et JWS sont omniprésents : access tokens OAuth en DSP2, ID Tokens OIDC (FranceConnect, EUDI Wallet), Request Objects JAR en FAPI, webhooks signés (Bridge, Tink, Plaid) et Verifiable Credentials EUDI en SD-JWT.
Exemples concrets
- Stripe webhooks : signés en HMAC SHA-256, format proche de JWS.
- Auth0, Okta, Cognito : émettent des JWT.
- OBIE UK : access tokens et ID Tokens en JWT PS256.
- EUDI Wallet : credentials en SD-JWT (prouver « majeur » sans révéler la date de naissance).
- FranceConnect : ID Tokens JWT.
- Vulnérabilité 2018 : faille « confusion d'algo » corrigée globalement dans les librairies.
- Outils : jwt.io (debugger),
jose(JS), PyJWT, java-jwt, jose4j.