Message d’erreur
TypeError: "ES256" signatures must be "64" bytes, saw "71"
Également affiché sous la forme
- "ES256" signatures must be "64" bytes, saw "70"
- "ES256" signatures must be "64" bytes, saw "72"
- "ES384" signatures must be "96" bytes, saw "103"
- "ES512" signatures must be "132" bytes, saw "139"
Le nombre qui suit « saw » varie entre 70 et 72 pour ES256 (la longueur DER dépend des bits de poids fort de r et de s) ; ES384 attend 96 octets et ES512 132. L’erreur est un simple `TypeError`, pas un `JsonWebTokenError` : les tests `instanceof` portant sur les erreurs de jsonwebtoken ne l’interceptent donc pas.
jsonwebtoken / jws / jwa (Node.js) — TypeError from ecdsa-sig-formatter
Ce que cela signifie
Le segment de signature du jeton se décode en 71 octets, alors qu’une signature JWS ES256 doit faire exactement 64 octets : la concaténation brute r‖s définie dans la RFC 7518 §3.4. Une valeur de 70 à 72 octets qui commence par `0x30` est l’encodage ASN.1 DER de la même signature, c’est-à-dire le format que produisent par défaut OpenSSL, Java, les services KMS et `crypto.sign()` de Node. Le jeton a été créé par un signataire qui a omis la conversion de DER vers brut ; jsonwebtoken (via ecdsa-sig-formatter) le rejette avant toute vérification.
Pourquoi cela se produit
Un signataire fait maison a produit du DER
fréquenteUn code qui construit lui-même le JWT et signe avec `crypto.sign("sha256", data, key)` ou `createSign().sign(key)` obtient une sortie DER, sauf s’il passe `dsaEncoding: "ieee-p1363"`. Le jeton paraît correct partout, jusqu’à ce qu’un vérificateur conforme aux normes contrôle la longueur.
Un KMS ou un HSM a signé le jeton
fréquente`Sign` d’AWS KMS et `asymmetricSign` de Google Cloud KMS renvoient les signatures ECDSA en DER : une signature JWT qui s’appuie sur eux nécessite donc une étape de conversion explicite. (Azure Key Vault et `CKM_ECDSA` de PKCS#11 renvoient déjà r‖s brut : vérifiez ce que documente votre fournisseur avant de convertir.)
Encodage par défaut d’un autre langage
occasionnelle`SHA256withECDSA` de Java, `sign()` de la bibliothèque Python cryptography, `ecdsa.SignASN1` de Go et la CLI OpenSSL produisent tous du DER. Les bibliothèques conçues pour JOSE convertissent automatiquement ; les appels cryptographiques génériques, non.
Le segment de signature est corrompu
rareSi la longueur signalée n’est pas comprise entre 70 et 72 (par exemple « saw 2 »), le troisième segment a été tronqué ou remplacé, et non encodé différemment.
Comment corriger l’erreur
- 1.
Demander r‖s brut à node:crypto
`dsaEncoding: "ieee-p1363"` fait produire à Node le format de longueur fixe qu’exige JWS. Mieux encore, signez avec une bibliothèque JOSE (`jwt.sign` de jsonwebtoken, `SignJWT` de jose), qui s’en charge pour vous.
js import { sign } from "node:crypto"; const signature = sign("sha256", Buffer.from(signingInput), { key: privateKey, dsaEncoding: "ieee-p1363", // raw r||s: 64 bytes for P-256, as RFC 7518 §3.4 requires }); const token = signingInput + "." + signature.toString("base64url"); - 2.
Convertir le DER d’un KMS avant d’assembler le jeton
`ecdsa-sig-formatter` (installé avec jsonwebtoken via jws/jwa) convertit le DER au format JOSE. Le convertisseur DER ⇄ brut affiche r et s pour les deux formes, afin que vous puissiez confirmer la conversion.
js import ecdsaSigFormatter from "ecdsa-sig-formatter"; // AWS KMS and Google Cloud KMS return DER; convert once before assembling the JWS. const derSignature = Buffer.from(kmsResponse.Signature); const joseSignature = ecdsaSigFormatter.derToJose(derSignature, "ES256"); // base64url, 64 bytes decoded const token = signingInput + "." + joseSignature;