Message d’erreur
signature verification failed
jose (JavaScript) — JWSSignatureVerificationFailed, code ERR_JWS_SIGNATURE_VERIFICATION_FAILED
Ce que cela signifie
jose a analysé le JWS sans erreur et exécuté la vérification cryptographique, mais la signature ne se vérifie pas avec la clé qu’il a sélectionnée. La structure, l’algorithme et le type de clé étaient tous acceptables : ce sont simplement les calculs qui ne concordent pas, ce qui met en cause la clé ou des octets signés modifiés.
Pourquoi cela se produit
Mauvaise clé pour ce jeton
fréquenteLe vérificateur détient une autre clé que celle avec laquelle l’émetteur a signé : un JWKS après rotation dont l’ancien kid a disparu, une clé codée en dur devenue obsolète, ou une confusion d’environnements (vérificateur de préproduction, jeton de production).
Les octets signés ont changé entre le signataire et le vérificateur
fréquenteJWS signe le texte base64url exact de header.payload. Tout ce qui réencode ces segments – une passerelle qui normalise le remplissage base64, une resérialisation JSON, des caractères rognés pendant le transport – fait échouer la vérification, même si la charge utile décodée semble identique.
Un signataire ES256 fait maison a produit du DER
occasionnellecrypto.sign() de Node émet par défaut les signatures ECDSA en ASN.1 DER, mais la RFC 7518 exige que les signatures JWS ES256 soient au format brut r‖s (exactement 64 octets). Un jeton dont le troisième segment se décode en 70 à 72 octets environ, commençant par 0x30, a été signé dans le mauvais format.
Comment corriger l’erreur
- 1.
Résoudre les clés par kid à partir du JWKS de l’émetteur
Laissez jose choisir la bonne clé pour chaque jeton au lieu d’en épingler une manuellement ; createRemoteJWKSet met les clés en cache et les actualise au fil des rotations.
js import { createRemoteJWKSet, jwtVerify } from "jose"; const jwks = createRemoteJWKSet(new URL("https://issuer.example/.well-known/jwks.json")); const { payload } = await jwtVerify(token, jwks, { algorithms: ["ES256"], issuer: "https://issuer.example", }); - 2.
Avec node:crypto, produire des signatures r‖s brutes
Pour un signataire personnalisé, demandez une sortie au format IEEE P1363 afin que la signature ait le format de 64 octets qu’exige JWS – ou vérifiez ce que votre signataire a produit en contrôlant la longueur du troisième segment.
js import { sign } from "node:crypto"; const sig = sign("sha256", Buffer.from(signingInput), { key: privateKey, dsaEncoding: "ieee-p1363", // raw r||s, 64 bytes for P-256 }); - 3.
Vérifier la forme du segment de signature
Décodez le troisième segment du jeton : 64 octets signifient un r‖s brut (correct pour ES256) ; environ 70 octets commençant par 0x30 signifient du DER. Le convertisseur DER ⇄ brut ci-dessous affiche les valeurs r et s et convertit d’un format à l’autre.