{"record":{"id":"90e23622bd2854b8","repo":"jwtk/jjwt","slug":"unable-to-derive-rsapublickey-from-rsaprivatekey","errorCode":null,"errorMessage":"Unable to derive RSAPublicKey from RSAPrivateKey ${ctx}. Cause: ${e.getMessage()}","messagePattern":"Unable to derive RSAPublicKey from RSAPrivateKey (.+?)\\. Cause: (.+?)","errorType":"exception","errorClass":"InvalidKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/RsaPrivateJwkFactory.java","lineNumber":97,"sourceCode":"        }\n\n        String msg = String.format(PUB_EXPONENT_EX_MSG, KeysBridge.toString(key));\n        throw new UnsupportedKeyException(msg);\n    }\n\n    private RSAPublicKey derivePublic(final JwkContext<RSAPrivateKey> ctx) {\n        RSAPrivateKey key = ctx.getKey();\n        BigInteger modulus = key.getModulus();\n        BigInteger publicExponent = getPublicExponent(key);\n        final RSAPublicKeySpec spec = new RSAPublicKeySpec(modulus, publicExponent);\n        return generateKey(ctx, RSAPublicKey.class, new CheckedFunction<KeyFactory, RSAPublicKey>() {\n            @Override\n            public RSAPublicKey apply(KeyFactory kf) {\n                try {\n                    return (RSAPublicKey) kf.generatePublic(spec);\n                } catch (Exception e) {\n                    String msg = \"Unable to derive RSAPublicKey from RSAPrivateKey \" + ctx + \". Cause: \" + e.getMessage();\n                    throw new InvalidKeyException(msg);\n                }\n            }\n        });\n    }\n\n    @Override\n    protected RsaPrivateJwk createJwkFromKey(JwkContext<RSAPrivateKey> ctx) {\n\n        RSAPrivateKey key = ctx.getKey();\n        RSAPublicKey rsaPublicKey;\n\n        PublicKey publicKey = ctx.getPublicKey();\n        if (publicKey != null) {\n            rsaPublicKey = Assert.isInstanceOf(RSAPublicKey.class, publicKey, PUBKEY_ERR_MSG);\n        } else {\n            rsaPublicKey = derivePublic(ctx);\n        }\n","sourceCodeStart":79,"sourceCodeEnd":115,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/RsaPrivateJwkFactory.java#L79-L115","documentation":"Thrown as InvalidKeyException when jjwt tries to derive the RSAPublicKey from an RSAPrivateKey's modulus and public exponent (via JCA KeyFactory.generatePublic with RSAPublicKeySpec) and the JCA provider rejects it. The message embeds the JwkContext and underlying cause.","triggerScenarios":"Creating a JWK from an RSAPrivateKey whose modulus or recovered public exponent is invalid/inconsistent, causing KeyFactory.generatePublic to fail inside the derivePublic path of RsaPrivateJwkFactory.","commonSituations":"Corrupted or truncated key encodings; keys with mismatched modulus/exponent pairs from custom deserialization; buggy or restrictive JCA providers.","solutions":["Check the wrapped cause message for the provider's exact rejection reason (invalid modulus, exponent, spec).","Verify the private key loads correctly and its CRT parameters are consistent (e.g. compare getModulus against a freshly loaded copy).","Supply the real RSAPublicKey alongside the private key so derivation is not needed, or regenerate the keypair with Jwts.SIG.RSxxx.keyPair()."],"exampleFix":"// before\nJwk<RSAPrivateKey> jwk = Jwts.CLK... // only private key provided, derivation fails\n// after\nKeyPair kp = Jwts.SIG.RS256.keyPair().build();\n// or build JWK from a keypair that includes a valid public key","handlingStrategy":"try-catch","validationCode":"RSAPublicKeySpec spec = new RSAPublicKeySpec(privKey.getModulus(), ((RSAPrivateCrtKey) privKey).getPublicExponent()); // test derivation yourself first","typeGuard":"boolean canDerivePublic(RSAPrivateKey k) { return k instanceof RSAPrivateCrtKey && k.getModulus() != null && ((RSAPrivateCrtKey) k).getPublicExponent() != null; }","tryCatchPattern":"try { /* create JWK */ } catch (InvalidKeyException e) { log.error(\"Public key derivation failed: {}\", e.getMessage()); throw e; }","preventionTips":["Verify modulus/publicExponent pair with KeyFactory before handing the key to jjwt.","Prefer providing the real KeyPair rather than relying on derivation.","Beware of keys mutated or partially deserialized by third-party code."],"tags":["rsa","jwk","key-derivation","invalid-key"],"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-17T15:17:12.973Z"}