jwtk/jjwt · error · io.jsonwebtoken.security.WeakKeyException

The RSA ${keyType} key size (aka modulus bit length) is ${si

Error message

The RSA ${keyType} 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.

What it means

This WeakKeyException indicates the RSA key's modulus bit length is below the JWA (RFC 7518) minimum of 2048 bits required for the RSA key-management algorithm. The library enforces the RFC minimum to prevent insecure JWE usage; section 4.2 applies to RSA1_5 and 4.3 to RSA-OAEP.

Source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/DefaultRsaKeyAlgorithm.java:79

        }

        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 {

        Assert.notNull(request, "Request cannot be null.");
        final PublicKey kek = Assert.notNull(request.getPayload(), "RSA PublicKey encryption key cannot be null.");
        validate(kek, true);
        final SecretKey cek = generateCek(request);

        byte[] ciphertext = jca(request).withCipher(new CheckedFunction<Cipher, byte[]>() {
            @Override
            public byte[] apply(Cipher cipher) throws Exception {
                if (SPEC == null) {
                    cipher.init(Cipher.WRAP_MODE, kek, ensureSecureRandom(request));
                } else {
                    cipher.init(Cipher.WRAP_MODE, kek, SPEC, ensureSecureRandom(request));

View on GitHub (pinned to fb71496164)

Solutions

  1. Generate a new RSA key pair with at least 2048 bits: KeyPairGenerator.getInstance("RSA").initialize(2048).
  2. Re-issue or rotate the key to 2048/3072/4096 bits and update the keystore.
  3. If you must inspect, check key.getModulus().bitLength() >= 2048 before use.
  4. Avoid reducing security by downgrading the algorithm; the RFC minimum is mandatory.

Example fix

// before
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
kg.initialize(1024);
// after
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
kg.initialize(2048);
KeyPair kp = kg.generateKeyPair();
Defensive patterns

Strategy: validation

Validate before calling

java.security.interfaces.RSAKey rk = (java.security.interfaces.RSAKey) key;
if (rk.getModulus().bitLength() < 2048) {
    throw new IllegalArgumentException("RSA key must be >= 2048 bits, was " + rk.getModulus().bitLength());
}

Type guard

boolean isStrongRsa(Key k) {
    return k instanceof java.security.interfaces.RSAKey
        && ((java.security.interfaces.RSAKey) k).getModulus().bitLength() >= 2048;
}

Try / catch

try {
    jwt = Jwts.builder().encryptWith(pub, Jwts.KEY.RSA_OAEP)...compact();
} catch (io.jsonwebtoken.security.WeakKeyException e) {
    // rotate to a >=2048-bit key
}

Prevention

When it happens

Trigger: Calling getEncryptionKey/getDecryptionKey with an RSA key smaller than 2048 bits, e.g. a 1024- or 512-bit key pair, when the key length is obtainable (not HSM/PKCS11-opaque).

Common situations: Legacy keys generated at 1024 bits; test keys generated with small sizes for speed; keys imported from old systems predating the 2048-bit requirement.

Related errors


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