跳到主要内容
ecdsa.com
jsonwebtoken (Node.js)JWT 库

错误信息

"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` 检查密钥的曲线,因此不匹配的密钥会被提前拒绝,而不会生成其他库都不接受的令牌。

原因

修复方法

  1. 1.

    打印密钥的曲线

    `asymmetricKeyDetails.namedCurve` 以 OpenSSL 的命名报告曲线。把它与令牌头部中的算法对照。

    js
    import { createPublicKey } from "node:crypto";
    
    const key = createPublicKey(pem);
    console.log(key.asymmetricKeyType, key.asymmetricKeyDetails); // ec { namedCurve: 'prime256v1' }
  2. 2.

    根据密钥确定算法

    如果同时在用不同大小的密钥,就根据密钥的曲线选择 JWS 算法,而不是硬编码 ES256,并在 JWKS 中发布同样的 `alg`。

    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. 3.

    需要 ES256 时生成 P-256 密钥

    ES256 是 JOSE 库中支持最广泛的 ECDSA 算法;生成新的 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

相关错误

浏览完整的签名错误库