Fehlermeldung
secretOrPublicKey must be an asymmetric key when using ES256
Was der Fehler bedeutet
Du hast jsonwebtoken ein ES256-Token prüfen lassen (oder signieren – die Schwestermeldung nennt secretOrPrivateKey), aber das übergebene Schlüsselmaterial ist ein symmetrisches Secret: ein einfacher String oder Buffer, der kein PEM/KeyObject ist. ES256 ist ECDSA auf P-256 und braucht ein EC-Schlüsselpaar, kein gemeinsames Geheimnis.
Warum der Fehler auftritt
Ein Secret aus der HMAC-Zeit, das in der Konfiguration geblieben ist
häufigDer Dienst hat HS256 mit einem gemeinsamen Geheimnis verwendet, jemand hat alg auf ES256 umgestellt, und JWT_SECRET enthält immer noch „supersecret“. Ein beliebiger String ist kein EC-Schlüssel, und jsonwebtoken weigert sich, so zu tun, als wäre er einer.
Die falsche Konfigurationsvariable ist eingebunden
häufigDas PEM existiert, aber der Code liest eine Variable, die etwas anderes enthält – eine Schlüssel-ID oder eine JWKS-URL (die URL https://issuer/.well-known/jwks.json ist ein String, kein Schlüssel). Eine leere Variable wird anders gemeldet, nämlich als „secret or public key must be provided“.
Das PEM wurde auf dem Weg durch die Konfiguration beschädigt
häufigEin PEM, das mit wörtlichen \n-Sequenzen ankommt, in Anführungszeichen eingeschlossen oder von einer YAML-Datei eingerückt ist, lässt sich nicht mehr als Schlüssel parsen, deshalb behandelt jsonwebtoken 9 den String als gemeinsames Geheimnis und meldet diesen Fehler. Stelle die Zeilenumbrüche wieder her und entferne die Anführungszeichen, bevor du das PEM übergibst.
JWK übergeben, wo PEM/KeyObject erwartet wird
gelegentlichEin JWK ist ein JSON-Objekt; wandelst du ihn in einen String um und übergibst ihn an jwt.verify(), erhältst du einen String, der weder PEM noch KeyObject ist. Er muss zuerst konvertiert werden (crypto.createPublicKey({ key: jwk, format: "jwk" })).
So behebst du den Fehler
- 1.
Echten öffentlichen Schlüssel vom Typ EC laden
Prüfe ES256 mit einem PEM (SPKI) oder einem KeyObject. Hast du einen JWK – zum Beispiel von einem JWKS-Endpunkt –, konvertiere ihn zuerst mit node:crypto.
js import { createPublicKey } from "node:crypto"; const key = createPublicKey({ key: jwk, format: "jwk" }); // or a PEM string jwt.verify(token, key, { algorithms: ["ES256"] }); - 2.
JWKS-Schlüssel mit einer Hilfsfunktion auflösen
Veröffentlicht dein Aussteller seine Schlüssel unter einer JWKS-URL, übergib nicht die URL als Schlüssel – löse den Schlüssel für jedes Token anhand von kid auf.
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"] }); - 3.
Oder: Eigentlich wolltest du HS256
Sind Aussteller und Verifizierer beide dein eigener Dienst und ist ein gemeinsames Geheimnis beabsichtigt, setze auf beiden Seiten algorithm: "HS256" statt ES256. Genau das Vermischen der beiden Familien verhindert dieser Fehler – einschließlich des klassischen Angriffsszenarios der Schlüsselverwechslung (Key Confusion).