jwtk/jjwt · error · io.jsonwebtoken.security.InvalidKeyException

ECPublicKey's ECPoint does not exist on elliptic curve '%s'

Error message

ECPublicKey's ECPoint does not exist on elliptic curve '%s' and may not be used to create '%s' JWKs.

What it means

EcPublicJwkFactory.createJwkFromKey verifies that the ECPublicKey's public point W actually lies on the declared elliptic curve before producing a JWK. If ECCurve.contains(curve, point) fails, the key is mathematically invalid for that curve and could be an invalid-curve attack vector, so creation is rejected.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/EcPublicJwkFactory.java:79

        if (c == null) {
            throw new InvalidKeyException(UNSUPPORTED_CURVE_MSG);
        }
        return c.getId();
    }

    @Override
    protected EcPublicJwk createJwkFromKey(JwkContext<ECPublicKey> ctx) {

        ECPublicKey key = ctx.getKey();

        ECParameterSpec spec = key.getParams();
        EllipticCurve curve = spec.getCurve();
        ECPoint point = key.getW();

        String curveId = getJwaIdByCurve(curve);
        if (!ECCurve.contains(curve, point)) {
            String msg = keyContainsErrorMessage(curveId);
            throw new InvalidKeyException(msg);
        }

        ctx.put(DefaultEcPublicJwk.CRV.getId(), curveId);

        String x = toOctetString(curve, point.getAffineX());
        ctx.put(DefaultEcPublicJwk.X.getId(), x);

        String y = toOctetString(curve, point.getAffineY());
        ctx.put(DefaultEcPublicJwk.Y.getId(), y);

        return new DefaultEcPublicJwk(ctx);
    }

    @Override
    protected EcPublicJwk createJwkFromValues(final JwkContext<ECPublicKey> ctx) {

        ParameterReadable reader = new RequiredParameterReader(ctx);
        String curveId = reader.get(DefaultEcPublicJwk.CRV);

View on GitHub (pinned to fb71496164)

Solutions

  1. Generate EC key pairs with KeyPairGenerator rather than constructing points manually.
  2. Validate the point satisfies the curve equation before building the key: check with ECCurve or a small BigInteger check y^2 = x^3 + ax + b (mod p).
  3. Re-export or re-import the key from a trusted source if the key material may be corrupted.
  4. Verify keys received from untrusted parties before use.

Example fix

// before
ECPoint badPoint = new ECPoint(x, y); // y not on curve
ECPublicKeySpec spec = new ECPublicKeySpec(badPoint, params);
KeyFactory kf = KeyFactory.getInstance("EC");
ECPublicKey key = (ECPublicKey) kf.generatePublic(spec);
// after
// generate a guaranteed-valid pair instead
KeyPairGenerator kg = KeyPairGenerator.getInstance("EC");
kg.initialize(new ECGenParameterSpec("secp256r1"));
ECPublicKey key = (ECPublicKey) kg.generateKeyPair().getPublic();
Defensive patterns

Strategy: validation

Validate before calling

BigInteger p = ((ECFieldFp) curve.getField()).getP();
boolean onCurve = point.getAffineY().pow(2).subtract(point.getAffineX().pow(3).add(curve.getA().multiply(point.getAffineX())).add(curve.getB())).mod(p).signum() == 0;
if (!onCurve) throw new IllegalArgumentException("ECPoint not on curve");

Try / catch

try {
    Jwk<?> jwk = Jwks.builder().setKey(ecPublicKey).build();
} catch (io.jsonwebtoken.security.InvalidKeyException e) {
    // regenerate or re-source the key pair
}

Prevention

When it happens

Trigger: Building a JWK from an ECPublicKey whose W point is not on its declared curve — e.g. hand-constructed ECPublicKeySpec, corrupted keystores, or maliciously supplied keys.

Common situations: Manually constructing public keys from raw coordinates with mismatched parameters; keys tampered with in transit; unit-test fixtures with invented points.

Related errors


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/139dfea2b19b2012. Report an issue: GitHub.