{"record":{"id":"397f14f55f3c759c","repo":"jwtk/jjwt","slug":"string-format-pub-exponent-ex-msg-keysbridge-to","errorCode":null,"errorMessage":"${String.format(PUB_EXPONENT_EX_MSG, KeysBridge.toString(key))}","messagePattern":"\\$\\{String\\.format\\(PUB_EXPONENT_EX_MSG, KeysBridge\\.toString\\(key\\)\\)\\}","errorType":"exception","errorClass":"UnsupportedKeyException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/RsaPrivateJwkFactory.java","lineNumber":82,"sourceCode":"\n    RsaPrivateJwkFactory() {\n        super(DefaultRsaPublicJwk.TYPE_VALUE, RSAPrivateKey.class, DefaultRsaPrivateJwk.PARAMS);\n    }\n\n    @Override\n    protected boolean supportsKeyValues(JwkContext<?> ctx) {\n        return super.supportsKeyValues(ctx) && ctx.containsKey(DefaultRsaPrivateJwk.PRIVATE_EXPONENT.getId());\n    }\n\n    private static BigInteger getPublicExponent(RSAPrivateKey key) {\n        if (key instanceof RSAPrivateCrtKey) {\n            return ((RSAPrivateCrtKey) key).getPublicExponent();\n        } else if (key instanceof RSAMultiPrimePrivateCrtKey) {\n            return ((RSAMultiPrimePrivateCrtKey) key).getPublicExponent();\n        }\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        });","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/RsaPrivateJwkFactory.java#L64-L100","documentation":"Thrown as UnsupportedKeyException from RsaPrivateJwkFactory.getPublicExponent when the given RSA private key is neither RSAPrivateCrtKey nor RSAMultiPrimePrivateCrtKey, so its public exponent cannot be read to derive/build the corresponding public JWK part. Only CRT-form RSA private keys expose the public exponent in the JCA API.","triggerScenarios":"Building a JWK from an RSAPrivateKey obtained from sources that produce non-CRT keys, e.g. RSAPrivateKey generated via certain KeyFactory/PKCS#1 'RSA' (not 'RSASSA-PSS'/CRT) specs, or keys deserialized from custom formats, when calling Jwts.builder header/JWK embedding or JwkBuilder with the private key.","commonSituations":"Keys loaded from PKCS#8 blobs whose KeyFactory yields plain RSAPrivateKey (two-integer) representations; keys converted through third-party crypto libraries; Android/legacy provider keys missing CRT fields.","solutions":["Load the private key with a CRT-capable KeyFactory (algorithm 'RSA' with PKCS8EncodedKeySpec usually yields RSAPrivateCrtKey; verify instanceof RSAPrivateCrtKey).","Re-export the key so CRT parameters (prime1/prime2/exponent1/exponent2/coefficient) are included (e.g. openssl with PKCS#8 which retains CRT fields).","Provide the matching RSAPublicKey explicitly instead of relying on derivation, or reconstruct a CRT key from stored CRT parameters."],"exampleFix":"// before\nKeyFactory kf = KeyFactory.getInstance(\"RSA\");\nRSAPrivateKey key = (RSAPrivateKey) kf.generatePrivate(spec); // may be non-CRT\n// after\nRSAPrivateKey key = (RSAPrivateKey) kf.generatePrivate(new PKCS8EncodedKeySpec(pkcs8Bytes));\nif (!(key instanceof RSAPrivateCrtKey)) {\n    throw new IllegalArgumentException(\"CRT-form RSA private key required\");\n}","handlingStrategy":"type-guard","validationCode":"if (!(privateKey instanceof RSAPrivateCrtKey) && !(privateKey instanceof RSAMultiPrimePrivateCrtKey)) throw new IllegalArgumentException(\"CRT-form RSA private key required\");","typeGuard":"boolean isCrtRsaKey(Key k) { return k instanceof RSAPrivateCrtKey || k instanceof RSAMultiPrimePrivateCrtKey; }","tryCatchPattern":"try { /* build JWK from private key */ } catch (UnsupportedKeyException e) { throw new IllegalStateException(\"Non-CRT RSA key; reload with CRT parameters\", e); }","preventionTips":["Always load RSA private keys via PKCS8EncodedKeySpec so CRT fields are present.","Check instanceof RSAPrivateCrtKey right after key loading.","Keep openssl exports in PKCS#8 format which preserves CRT parameters."],"tags":["rsa","jwk","unsupported-key","crt"],"backgroundTag":"unsupported-operation","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"}