Сообщение об ошибке
"alg" parameter "ES256" requires curve "prime256v1".
Также выводится как
- "alg" parameter "ES384" requires curve "secp384r1".
- "alg" parameter "ES512" requires curve "secp521r1".
Эту ошибку выбрасывают и `jwt.sign()`, и `jwt.verify()`. Требуемая кривая указывается в написании OpenSSL: `prime256v1`, `secp384r1`, `secp521r1`.
jsonwebtoken (Node.js) — Error from jwt.sign() / jwt.verify() key validation (v9+)
Что это означает
Переданный вами EC-ключ лежит не на той кривой, которую требует алгоритм. В JOSE каждый алгоритм ECDSA привязан ровно к одной кривой: ES256 — к P-256 (в OpenSSL она называется `prime256v1`), ES384 — к P-384 (`secp384r1`), ES512 — к P-521 (`secp521r1`). Начиная с версии 9, jsonwebtoken сверяет кривую ключа с `alg` перед подписью или проверкой, поэтому неподходящий ключ отклоняется сразу, а не порождает токены, которые не примет ни одна другая библиотека.
Почему это происходит
Ключ secp256k1 с ES256
частоsecp256k1 (Bitcoin, Ethereum) — другая 256-битная кривая. Её алгоритм в JOSE — `ES256K` (RFC 8812), а библиотека jsonwebtoken его не поддерживает; «256» в ES256 относится только к SHA-256 и P-256.
Ключ P-384 или P-521 с ES256
иногдаКлючи, сгенерированные OpenSSL с параметрами по умолчанию, ключи облачного KMS со спецификацией вроде `ECC_NIST_P384` или ключ сертификата, выпущенного по профилю CA, могут лежать на кривой большего размера. Выберите алгоритм, соответствующий ключу (ES384/ES512), или сгенерируйте ключ P-256.
Загружен не тот файл ключа
иногдаВ одном хранилище секретов лежит несколько ключей, и сервис читает тот, что предназначен для другой цели: ключ TLS, ключ SSH, ключ подписи для другой системы.
Как исправить
- 1.
Выведите кривую ключа
`asymmetricKeyDetails.namedCurve` возвращает имя кривой в нотации OpenSSL. Сравните его с алгоритмом в заголовке токена.
js import { createPublicKey } from "node:crypto"; const key = createPublicKey(pem); console.log(key.asymmetricKeyType, key.asymmetricKeyDetails); // ec { namedCurve: 'prime256v1' } - 2.
Определяйте алгоритм по ключу
Если используются ключи разного размера, выбирайте алгоритм JWS по кривой ключа, а не прописывайте ES256 жёстко в коде, и публикуйте тот же `alg` в своём JWKS.
js const ALG_BY_CURVE = { prime256v1: "ES256", secp384r1: "ES384", secp521r1: "ES512" }; const alg = ALG_BY_CURVE[key.asymmetricKeyDetails.namedCurve]; if (!alg) throw new Error("this curve has no JWS algorithm in jsonwebtoken"); const token = jwt.sign(claims, key, { algorithm: alg, expiresIn: "10m" }); - 3.
Если нужен ES256, сгенерируйте ключ P-256
ES256 — самый широко поддерживаемый алгоритм ECDSA в библиотеках JOSE, а новая пара ключей P-256 создаётся одной командой.
bash openssl genpkey -algorithm EC -pkeyopt ec_paramgen_curve:P-256 -out es256-private.pem openssl pkey -in es256-private.pem -pubout -out es256-public.pem