{"record":{"id":"a3a486ceede67e12","repo":"jwtk/jjwt","slug":"the-provided-elliptic-curve-keytype-key-size-a","errorCode":null,"errorMessage":"The provided Elliptic Curve ${keyType} key size (aka order bit length) is ${size}, but the '${id}' algorithm requires EC Keys with ${orderBitLength} per [RFC 7518, Section 3.4](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.4).","messagePattern":"The provided Elliptic Curve (.+?) key size \\(aka order bit length\\) is (.+?), but the '(.+?)' algorithm requires EC Keys with (.+?) per \\[RFC 7518, Section 3\\.4\\]\\(https://www\\.rfc-editor\\.org/rfc/rfc7518\\.html#section-3\\.4\\)\\.","errorType":"exception","errorClass":"io.jsonwebtoken.security.InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/EcSignatureAlgorithm.java","lineNumber":159,"sourceCode":"                .random(Randoms.secureRandom());\n    }\n\n    @Override\n    protected void validateKey(Key key, boolean signing) {\n        super.validateKey(key, signing);\n        if (!KEY_ALG_NAMES.contains(KeysBridge.findAlgorithm(key))) {\n            throw new InvalidKeyException(\"Unrecognized EC key algorithm name.\");\n        }\n        int size = KeysBridge.findBitLength(key);\n        if (size < 0) return; // likely PKCS11 or HSM key, can't get the data we need\n        int sigFieldByteLength = Bytes.length(size);\n        int concatByteLength = sigFieldByteLength * 2;\n        if (concatByteLength != this.signatureByteLength) {\n            String msg = \"The provided Elliptic Curve \" + keyType(signing) +\n                    \" key size (aka order bit length) is \" + Bytes.bitsMsg(size) + \", but the '\" +\n                    getId() + \"' algorithm requires EC Keys with \" + Bytes.bitsMsg(this.orderBitLength) +\n                    \" per [RFC 7518, Section 3.4](https://www.rfc-editor.org/rfc/rfc7518.html#section-3.4).\";\n            throw new InvalidKeyException(msg);\n        }\n    }\n\n    @Override\n    protected byte[] doDigest(final SecureRequest<InputStream, PrivateKey> request) {\n        return jca(request).withSignature(new CheckedFunction<Signature, byte[]>() {\n            @Override\n            public byte[] apply(Signature sig) throws Exception {\n                sig.initSign(KeysBridge.root(request));\n                byte[] signature = sign(sig, request.getPayload());\n                return transcodeDERToConcat(signature, signatureByteLength);\n            }\n        });\n    }\n\n    boolean isValidRAndS(PublicKey key, byte[] concatSignature) {\n        if (key instanceof ECKey) { //Some PKCS11 providers and HSMs won't expose the ECKey interface, so we have to check first\n            ECKey ecKey = (ECKey) key;","sourceCodeStart":141,"sourceCodeEnd":177,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/EcSignatureAlgorithm.java#L141-L177","documentation":"JJWT's EC signature algorithms (ES256/ES384/ES512) require an EC key whose order bit length exactly matches the algorithm's expected size (256, 384, or 512 bits). During key validation the actual key size was compared against the required orderBitLength and did not match, so an InvalidKeyException is thrown referencing RFC 7518 Section 3.4. This guards against signing/verifying with a key too weak or too strong for the chosen algorithm.","triggerScenarios":"Calling Jwts.builder().signWith(key, SignatureAlgorithm.ES256) (or parse-time verifyWith) with an EC PrivateKey/PublicKey whose curve is not exactly P-256/384/521 — e.g. a P-224, secp256k1, or P-521 key paired with ES256.","commonSituations":"Generating keys with OpenSSL default curves (secp256k1) instead of NIST P-curves; reusing one P-384 key across services configured for ES256; migrating from HS256 to ES256 while keeping old key files; picking a curve by habit ('stronger is better') without matching the algorithm.","solutions":["Regenerate or obtain an EC key on the curve matching the algorithm: P-256 for ES256, P-384 for ES384, P-521 for ES512","If the key is intentional, change the algorithm to the one matching its size (e.g. ES384 for a 384-bit key)","Print key size before use: KeyPairGenerator.getInstance(\"EC\").initialize(256) — or check ((ECPublicKey)key).getParams().getOrder().bitLength()"],"exampleFix":"// before\nKeyPairGenerator kpg = KeyPairGenerator.getInstance(\"EC\"); // provider default curve, may not be 256-bit\nKeyPair kp = kpg.generateKeyPair();\nString jwt = Jwts.builder().signWith(kp.getPrivate(), SignatureAlgorithm.ES256).compact();\n// after\nKeyPairGenerator kpg = KeyPairGenerator.getInstance(\"EC\");\nkpg.initialize(new ECGenParameterSpec(\"secp256r1\")); // P-256 == ES256 requirement\nKeyPair kp = kpg.generateKeyPair();\nString jwt = Jwts.builder().signWith(kp.getPrivate(), SignatureAlgorithm.ES256).compact();","handlingStrategy":"validation","validationCode":"boolean ecKeyMatches(PrivateKey key, String alg) {\n  ECParameterSpec p = ((ECPrivateKey) key).getParams();\n  int bits = p.getOrder().bitLength();\n  int required = alg.equals(\"ES256\") ? 256 : alg.equals(\"ES384\") ? 384 : 521;\n  return bits == required;\n}","typeGuard":"boolean isP256Key(PrivateKey k) {\n  return k instanceof ECPrivateKey\n    && ((ECPrivateKey) k).getParams().getOrder().bitLength() == 256;\n}","tryCatchPattern":"try {\n  String jwt = Jwts.builder().signWith(ecKey, SignatureAlgorithm.ES256).compact();\n} catch (InvalidKeyException e) {\n  throw new IllegalStateException(\"EC key curve does not match ES256 (need 256-bit order)\", e);\n}","preventionTips":["Initialize KeyPairGenerator explicitly with ECGenParameterSpec (secp256r1/secp384r1/secp521r1)","Check ((ECKey) key).getParams().getOrder().bitLength() at startup, before signing anything","Keep one curve-to-algorithm mapping table in config and derive the algorithm from the key, not vice versa"],"tags":["jwt","ecdsa","invalid-key","key-size"],"backgroundTag":"invalid-argument-value","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"}