{"record":{"id":"68c86edd55f5caa9","repo":"jwtk/jjwt","slug":"ec-jwk-x-y-coordinates-do-not-exist-on-elliptic-cu","errorCode":null,"errorMessage":"EC JWK x,y coordinates do not exist on elliptic curve '%s'. This could be due simply to an incorrectly-created JWK or possibly an attempted Invalid Curve Attack (see https://safecurves.cr.yp.to/twist.html for more information).","messagePattern":"EC JWK x,y coordinates do not exist on elliptic curve '(.+?)'\\. This could be due simply to an incorrectly-created JWK or possibly an attempted Invalid Curve Attack \\(see https://safecurves\\.cr\\.yp\\.to/twist\\.html for more information\\)\\.","errorType":"exception","errorClass":"io.jsonwebtoken.security.InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/EcPublicJwkFactory.java","lineNumber":106,"sourceCode":"        ctx.put(DefaultEcPublicJwk.Y.getId(), y);\n\n        return new DefaultEcPublicJwk(ctx);\n    }\n\n    @Override\n    protected EcPublicJwk createJwkFromValues(final JwkContext<ECPublicKey> ctx) {\n\n        ParameterReadable reader = new RequiredParameterReader(ctx);\n        String curveId = reader.get(DefaultEcPublicJwk.CRV);\n        BigInteger x = reader.get(DefaultEcPublicJwk.X);\n        BigInteger y = reader.get(DefaultEcPublicJwk.Y);\n\n        ECCurve curve = getCurveByJwaId(curveId);\n        ECPoint point = new ECPoint(x, y);\n\n        if (!curve.contains(point)) {\n            String msg = jwkContainsErrorMessage(curveId, ctx);\n            throw new InvalidKeyException(msg);\n        }\n\n        final ECPublicKeySpec pubSpec = new ECPublicKeySpec(point, curve.toParameterSpec());\n        ECPublicKey key = generateKey(ctx, new CheckedFunction<KeyFactory, ECPublicKey>() {\n            @Override\n            public ECPublicKey apply(KeyFactory kf) throws Exception {\n                return (ECPublicKey) kf.generatePublic(pubSpec);\n            }\n        });\n\n        ctx.setKey(key);\n\n        return new DefaultEcPublicJwk(ctx);\n    }\n}\n","sourceCodeStart":88,"sourceCodeEnd":122,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/EcPublicJwkFactory.java#L88-L122","documentation":"EcPublicJwkFactory.createJwkFromValues validates that the x,y coordinate pair parsed from JWK JSON values lies on the named elliptic curve. If it does not, the JWK was created incorrectly or the input may be an attempted Invalid Curve Attack, so the factory throws InvalidKeyException and refuses to materialize the key.","triggerScenarios":"Parsing or creating a JWK from map values (e.g. Jwks.parser().parse(...)) where x and y are valid Base64URL integers but not a valid curve point for the crv value; maliciously crafted JWK sets from untrusted sources.","commonSituations":"Accepting JWKs from third parties without validation; hand-written JWK JSON with a typo in x or y; attackers substituting low-order points to exploit invalid-curve vulnerabilities.","solutions":["Verify the source of the JWK data; only trust JWK sets from authenticated/HTTPS key endpoints.","Fix transcription errors in x/y values and ensure crv matches the coordinates.","Regenerate the key pair and re-serialize the JWK.","Keep jjwt up to date — this on-curve check is itself the library's mitigation against invalid curve attacks."],"exampleFix":"// before\n// x from curve A, y from curve B (mismatch)\nJwk jwk = Jwks.parser().build().parse(\"{\\\"kty\\\":\\\"EC\\\",\\\"crv\\\":\\\"P-256\\\",\\\"x\\\":\\\"...\\\",\\\"y\\\":\\\"WRONG\\\"}\");\n// after\n// re-serialize from a valid key pair\nKeyPair kp = kg.generateKeyPair();\nJwk jwk = Jwks.builder().setKey(kp.getPublic()).build();","handlingStrategy":"validation","validationCode":"// decode x,y into BigInteger and verify y^2 = x^3 + ax + b (mod p) for the crv curve before parsing\nboolean onCurve(BigInteger x, BigInteger y, EllipticCurve c) {\n    BigInteger p = ((ECFieldFp) c.getField()).getP();\n    return y.pow(2).subtract(x.pow(3).add(c.getA().multiply(x)).add(c.getB())).mod(p).signum() == 0;\n}","typeGuard":null,"tryCatchPattern":"try {\n    Jwk<?> jwk = Jwks.parser().build().parse(json);\n} catch (io.jsonwebtoken.security.InvalidKeyException e) {\n    // reject the JWK as malformed or hostile (possible invalid curve attack)\n}","preventionTips":["Only accept JWKs from trusted, TLS-protected endpoints","Log and reject off-curve coordinates — treat as a security event","Keep jjwt updated to retain on-curve validation fixes"],"tags":["java","jjwt","ec","jwk","invalid-curve-attack","security"],"backgroundTag":"invalid-curve-point","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}