{"record":{"id":"979051e397dd6941","repo":"jwtk/jjwt","slug":"privatekeys-may-not-be-used-to-encrypt-data-publi","errorCode":null,"errorMessage":"PrivateKeys may not be used to encrypt data. PublicKeys are used to encrypt, and PrivateKeys are used to decrypt.","messagePattern":"PrivateKeys may not be used to encrypt data\\. PublicKeys are used to encrypt, and PrivateKeys are used to decrypt\\.","errorType":"exception","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java","lineNumber":296,"sourceCode":"        return signWith(key, alg);\n    }\n\n    @Override\n    public JwtBuilder encryptWith(SecretKey key, AeadAlgorithm enc) {\n        if (key instanceof Password) {\n            return encryptWith((Password) key, new Pbes2HsAkwAlgorithm(enc.getKeyBitLength()), enc);\n        }\n        return encryptWith(key, Jwts.KEY.DIRECT, enc);\n    }\n\n    @Override\n    public <K extends Key> JwtBuilder encryptWith(final K key, final KeyAlgorithm<? super K, ?> keyAlg, final AeadAlgorithm enc) {\n        this.enc = Assert.notNull(enc, \"Encryption algorithm cannot be null.\");\n        Assert.hasText(enc.getId(), \"Encryption algorithm id cannot be null or empty.\");\n\n        Assert.notNull(key, \"Encryption key cannot be null.\");\n        if (key instanceof PrivateKey) {\n            throw new IllegalArgumentException(PRIV_KEY_ENC_MSG);\n        }\n        Assert.notNull(keyAlg, \"KeyAlgorithm cannot be null.\");\n        final String algId = Assert.hasText(keyAlg.getId(), \"KeyAlgorithm id cannot be null or empty.\");\n\n        this.key = key;\n        //noinspection unchecked\n        this.keyAlg = (KeyAlgorithm<Key, ?>) keyAlg;\n        final KeyAlgorithm<Key, ?> alg = this.keyAlg;\n\n        final String cekMsg = \"Unable to obtain content encryption key from key management algorithm '%s'.\";\n        this.keyAlgFunction = Functions.wrap(alg::getEncryptionKey, SecurityException.class, cekMsg, algId);\n\n        return this;\n    }\n\n    @Override\n    public JwtBuilder compressWith(CompressionAlgorithm alg) {\n        Assert.notNull(alg, \"CompressionAlgorithm cannot be null\");","sourceCodeStart":278,"sourceCodeEnd":314,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/DefaultJwtBuilder.java#L278-L314","documentation":"For JWE encryption, data is encrypted with the recipient's PublicKey (asymmetric key management) — PrivateKeys decrypt. Encrypting with a PrivateKey is cryptographically incorrect, so encryptWith rejects it with an IllegalArgumentException.","triggerScenarios":"JwtBuilder.encryptWith(privateKey, keyAlg, enc) where the key argument is a java.security.PrivateKey.","commonSituations":"Reusing the signing (private) key object in the encryption call; mixing up encrypt/decrypt sides of an asymmetric JWE flow; keystore alias loading the wrong entry.","solutions":["Pass the recipient's PublicKey to encryptWith; keep the PrivateKey only for decryption on the recipient side.","Add a guard: if (key instanceof PrivateKey) throw/redirect to the correct key before calling the builder.","Fix configuration/keystore lookup so encryption code receives public keys.","Catch IllegalArgumentException and log a key-role configuration error."],"exampleFix":"// before\nbuilder.encryptWith(myPrivateKey, Jwts.KEY.RSA_OAEP, Jwts ENC.A256GCM);\n// after\nbuilder.encryptWith(recipientPublicKey, Jwts.KEY.RSA_OAEP, Jwts.ENC.A256GCM);","handlingStrategy":"validation","validationCode":"if (key instanceof PrivateKey) throw new IllegalArgumentException(\"encryptWith requires a PublicKey\");","typeGuard":"boolean canEncrypt(Key k) { return !(k instanceof PrivateKey) && k != null; }","tryCatchPattern":"try { builder.encryptWith(key, keyAlg, enc); } catch (IllegalArgumentException e) { /* wrong key role */ }","preventionTips":["Encrypt with the recipient's PublicKey; decrypt only with the PrivateKey","Type helper parameters as PublicKey for encryption APIs","Verify keystore aliases resolve to keys with the expected role"],"tags":["jwt","jwe","encryption","key-misuse"],"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"}