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

  1. Use a key pair generated with KeyPairGenerator.getInstance("RSA") for encryption/decryption, not "RSASSA-PSS".
  2. Keep separate key pairs: a PSS pair for PS256 signatures and an RSA pair for JWE key management.
  3. 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

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


AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09). Data as JSON: /api/errors/865c2e514ad6ccaa. Report an issue: GitHub.