Message d’erreur
invalid signature
Ce que cela signifie
Le jeton a été analysé sans problème et sa structure est valide, mais le contrôle cryptographique a échoué : la signature sur header.payload ne se vérifie pas avec la clé que vous avez fournie. Soit la clé n’est pas celle qui a signé le jeton, soit les octets signés ont changé après la signature.
Pourquoi cela se produit
Vérification avec la mauvaise clé
fréquenteDe loin le cas le plus fréquent : l’environnement contient une autre clé que celle utilisée par l’émetteur, qu’il s’agisse d’une clé publique obsolète après une rotation, d’une clé de préproduction face à des jetons de production, ou d’un kid du JWKS qui ne correspond pas, parce que le vérificateur fige une clé alors que l’émetteur signe avec une autre.
Un code de signature maison a signé les mauvais octets
occasionnelleLe code qui construit des jetons à la main doit signer les octets ASCII de base64url(header).base64url(payload) avec SHA-256 et produire le r‖s brut de 64 octets qu’exige la RFC 7518 pour ES256. Signer le JSON lui-même, des segments en base64 standard ou un condensat SHA-384 sous un en-tête ES256 produit une signature bien formée qui ne se vérifie jamais. (Une signature encodée en DER est rejetée avant le contrôle, avec « "ES256" signatures must be "64" bytes », et un PEM abîmé par une variable d’environnement n’est pas du tout accepté comme clé : il échoue avec « secretOrPublicKey must be an asymmetric key when using ES256 ».)
Le jeton a été modifié après la signature
occasionnelleUn proxy, un outil de journalisation ou un client a resérialisé le JSON de la charge utile ou y a modifié des caractères. Un seul caractère modifié dans l’en-tête ou la charge utile suffit à invalider la signature : c’est tout l’intérêt de signer. (Un remplissage Base64 ajouté à un segment échoue une étape plus tôt, avec « invalid token » ; un jeton tronqué échoue avec « jwt malformed » ou avec une erreur de longueur de signature.)
Comment corriger l’erreur
- 1.
Calculer l’empreinte de la clé des deux côtés
Calculez le condensat de la clé publique que le vérificateur a réellement chargée et comparez-le à celui de la clé de l’émetteur. Des empreintes différentes signifient une clé obsolète ou erronée (de loin la cause la plus fréquente) et mettent fin à la recherche en une seule étape.
js import { createHash, createPublicKey } from "node:crypto"; // Run on the verifier, and on the issuer with its signing key: the outputs must match. const spki = createPublicKey(process.env.JWT_PUBLIC_KEY).export({ type: "spki", format: "der" }); console.log(createHash("sha256").update(spki).digest("hex")); - 2.
Faire correspondre le kid du jeton à la clé de vérification
Décodez l’en-tête sans vérification et comparez son kid avec la clé que vous détenez. Si l’émetteur publie un JWKS, résolvez la clé par kid au lieu d’en coder une en dur.
js const { header } = jwt.decode(token, { complete: true }); console.log(header.kid, header.alg); // compare with your JWKS / configured key - 3.
Laisser le débogueur identifier l’incohérence
Collez le jeton et la clé publique dans le débogueur JWT : il vérifie ES256/ES384/ES512 localement et distingue mauvaise clé, charge utile altérée et encodage de signature mal formé, au lieu de renvoyer un simple booléen.