Fehlermeldung
TypeError: "ES256" signatures must be "64" bytes, saw "71"
Auch ausgegeben als
- "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"
Die Zahl nach „saw“ liegt bei ES256 zwischen 70 und 72 (die DER-Länge hängt von den führenden Bits von r und s ab); ES384 erwartet 96 Byte, ES512 132. Der Fehler ist ein einfacher `TypeError`, kein `JsonWebTokenError`, deshalb fangen Prüfungen mit `instanceof` auf Fehler von jsonwebtoken ihn nicht ab.
jsonwebtoken / jws / jwa (Node.js) — TypeError from ecdsa-sig-formatter
Was der Fehler bedeutet
Das Signatursegment des Tokens ergibt dekodiert 71 Byte, eine ES256-JWS-Signatur muss aber genau 64 Byte lang sein: die rohe Verkettung r‖s nach RFC 7518 §3.4. Ein Wert von 70–72 Byte, der mit `0x30` beginnt, ist die ASN.1-DER-Kodierung derselben Signatur – das Format, das OpenSSL, Java, KMS-Dienste und `crypto.sign()` von Node standardmäßig erzeugen. Das Token stammt von einem Signierer, der die Umwandlung von DER in das rohe Format ausgelassen hat; jsonwebtoken (über ecdsa-sig-formatter) lehnt es vor jeder Prüfung ab.
Warum der Fehler auftritt
Ein selbst gebauter Signierer hat DER ausgegeben
häufigCode, der das JWT selbst baut und mit `crypto.sign("sha256", data, key)` oder `createSign().sign(key)` signiert, erhält DER als Ausgabe, sofern er nicht `dsaEncoding: "ieee-p1363"` übergibt. Das Token sieht überall unauffällig aus, bis ein standardkonformer Prüfer die Länge prüft.
Ein KMS oder HSM hat das Token signiert
häufig`Sign` von AWS KMS und `asymmetricSign` von Google Cloud KMS liefern ECDSA-Signaturen in DER, deshalb braucht eine darauf aufbauende JWT-Signierung einen expliziten Umwandlungsschritt. (Azure Key Vault und `CKM_ECDSA` aus PKCS#11 liefern bereits rohes r‖s – prüfe, was dein Provider dokumentiert, bevor du umwandelst.)
Die Standardkodierung einer anderen Sprache
gelegentlich`SHA256withECDSA` in Java, `sign()` aus der Python-Bibliothek cryptography, `ecdsa.SignASN1` in Go und die OpenSSL-CLI erzeugen alle DER. Für JOSE gebaute Bibliotheken wandeln automatisch um, generische Krypto-Aufrufe nicht.
Das Signatursegment ist beschädigt
seltenLiegt die gemeldete Länge nicht im Bereich 70–72 (etwa „saw 2“), wurde das dritte Segment abgeschnitten oder ersetzt, nicht anders kodiert.
So behebst du den Fehler
- 1.
Rohes r‖s von node:crypto anfordern
Mit `dsaEncoding: "ieee-p1363"` gibt Node das Format fester Länge aus, das JWS verlangt. Noch besser: Signiere mit einer JOSE-Bibliothek (`jwt.sign` von jsonwebtoken, `SignJWT` von jose), die das für dich erledigt.
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.
DER aus einem KMS umwandeln, bevor du das Token zusammensetzt
`ecdsa-sig-formatter` (wird mit jsonwebtoken über jws/jwa installiert) wandelt DER in das JOSE-Format um. Der Konverter DER ⇄ Raw zeigt r und s für beide Formen, damit du die Umwandlung bestätigen kannst.
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;