jwtk/jjwt · error · io.jsonwebtoken.security.InvalidKeyException
RSASSA-PSS keys may not be used for ${keyType}, only digital
Error message
RSASSA-PSS keys may not be used for ${keyType}, only digital signature algorithms. What it means
RSASSA-PSS keys (algorithm name 'RSASSA-PSS' / 'PSS') may only be used for digital signature algorithms, not for key-management (encryption) algorithms. DefaultRsaKeyAlgorithm.validate explicitly rejects them when used with RSA-OAEP or RSA1_5 because JWA forbids PSS keys in key-encryption roles.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithm.java:66
public DefaultRsaKeyAlgorithm(String id, String jcaTransformationString, AlgorithmParameterSpec spec) {
super(id, jcaTransformationString);
this.SPEC = spec; //can be null
}
private static String keyType(boolean encryption) {
return encryption ? "encryption" : "decryption";
}
protected void validate(Key key, boolean encryption) { // true = encryption, false = decryption
if (!RsaSignatureAlgorithm.isRsaAlgorithmName(key)) {
throw new InvalidKeyException("Invalid RSA key algorithm name.");
}
if (RsaSignatureAlgorithm.isPss(key)) {
String msg = "RSASSA-PSS keys may not be used for " + keyType(encryption) +
", only digital signature algorithms.";
throw new InvalidKeyException(msg);
}
int size = KeysBridge.findBitLength(key);
if (size < 0) return; // can't validate size: material or length not available (e.g. PKCS11 or HSM)
if (size < MIN_KEY_BIT_LENGTH) {
String id = getId();
String section = id.startsWith("RSA1") ? "4.2" : "4.3";
String msg = "The RSA " + keyType(encryption) + " key size (aka modulus bit length) is " + size +
" bits which is not secure enough for the " + id + " algorithm. " +
"The JWT JWA Specification (RFC 7518, Section " + section + ") states that RSA keys MUST " +
"have a size >= " + MIN_KEY_BIT_LENGTH + " bits. See " +
"https://www.rfc-editor.org/rfc/rfc7518.html#section-" + section + " for more information.";
throw new WeakKeyException(msg);
}
}
@Override
public KeyResult getEncryptionKey(final KeyRequest<PublicKey> request) throws SecurityException {View on GitHub (pinned to fb71496164)
Solutions
- Use a key pair generated with KeyPairGenerator.getInstance("RSA") for encryption/decryption, not "RSASSA-PSS".
- Keep separate key pairs: a PSS pair for PS256 signatures and an RSA pair for JWE key management.
- Switch the JWE algorithm to a signature-appropriate flow if you actually intended signing.
Example fix
// before
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSASSA-PSS");
Jwts.builder().encryptWith(kp.getPublic(), Jwts.KEY.RSA_OAEP)...
// after
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
kg.initialize(2048);
KeyPair kp = kg.generateKeyPair();
Jwts.builder().encryptWith(kp.getPublic(), Jwts.KEY.RSA_OAEP)... Defensive patterns
Strategy: validation
Validate before calling
if ("RSASSA-PSS".equalsIgnoreCase(key.getAlgorithm()) || "PSS".equalsIgnoreCase(key.getAlgorithm())) {
throw new IllegalArgumentException("PSS keys are signature-only; use a plain RSA key for JWE encryption");
} Type guard
boolean isPlainRsa(Key k) { return k instanceof java.security.interfaces.RSAKey && "RSA".equalsIgnoreCase(k.getAlgorithm()); } Try / catch
try {
jwt = Jwts.builder().encryptWith(pub, Jwts.KEY.RSA_OAEP)...compact();
} catch (io.jsonwebtoken.security.InvalidKeyException e) {
// fall back to a plain-RSA key pair
} Prevention
- Generate JWE key pairs with KeyPairGenerator.getInstance("RSA") not "RSASSA-PSS"
- Maintain distinct PSS signing and RSA encryption key pairs
When it happens
Trigger: Calling encryptWith(pssKeyPair.getPublic(), Jwts.KEY.RSA_OAEP) or the corresponding decryption with a PSS private key; keyType in the message is 'encryption' or 'decryption' depending on direction.
Common situations: Reusing the same RSA key pair for both JWS signing (PS256) and JWE encryption; keys generated with algorithm 'RSASSA-PSS' rather than 'RSA'.
Related errors
- Invalid RSA key algorithm name.
- Unexpected content JWE.
- Unexpected Claims JWE.
- The '${id}' algorithm requires keys with a length of ${bitsM
- The '${id}' algorithm requires ${type} with a length of ${bi
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/865c2e514ad6ccaa.
Report an issue: GitHub.