jwtk/jjwt · error · WeakKeyException

The RSA key size (aka modulus bit length) is bits which is…

Error message

The RSA ${keyType(signing)} 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.  Consider using the Jwts.SIG.${id}.keyPair() builder to create a KeyPair guaranteed to be secure enough for ${id}.  See https://tools.ietf.org/html/rfc7518#section-${section} for more information.

What it means

Thrown as WeakKeyException when an RSA signing/verification key's modulus bit length is below the minimum required by the algorithm (2048 bits for RS*/PS* per RFC 7518 sections 3.3/3.5). jjwt enforces JWA minimum key sizes to prevent insecure signatures.

Solutions

  1. Generate a new RSA keypair of >= 2048 bits, ideally with Jwts.SIG.RS256.keyPair().build() or openssl genrsa 2048.
  2. Rotate stored keys and update all verification parties with the new public key.
  3. If truly needed for legacy interop, use an explicit weaker configuration only in test environments (not recommended).

Example fix

// before
KeyPairGenerator kg = KeyPairGenerator.getInstance("RSA");
kg.initialize(1024);
// after
KeyPair kp = Jwts.SIG.RS256.keyPair().build(); // 2048-bit by default
Defensive patterns

Strategy: validation

Validate before calling

RSAPublicKey pub = (RSAPublicKey) keyPair.getPublic();
if (pub.getModulus().bitLength() < 2048) throw new IllegalStateException("RSA key too small for RS*/PS*");

Type guard

boolean strongEnough(RSAPublicKey k) { return k.getModulus().bitLength() >= 2048; }

Try / catch

try { /* sign/verify */ } catch (WeakKeyException e) { throw new IllegalStateException("Rotate to a >= 2048-bit RSA key", e); }

Prevention

When it happens

Trigger: Signing or verifying a JWT with an RSA key smaller than 2048 bits (e.g. legacy 1024-bit keys) with RS256/RS384/RS512/PS256/PS384/PS512 via Jwts.builder().signWith or parser verification.

Common situations: Legacy test/development keys (512/768/1024-bit) still used in production; keys generated years ago with outdated tooling; unit tests with fast small keys.

Understand the failure class

Background: "value must be between 0 and 1" / "out of range" / "must not be negative" errors: fixing range-validation failures across open-source libraries — this error's family across 42 libraries.

Related errors


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

Appendix: source

Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/RsaSignatureAlgorithm.java:197

    @Override
    protected void validateKey(Key key, boolean signing) {
        super.validateKey(key, signing);
        if (!isRsaAlgorithmName(key)) {
            throw new InvalidKeyException("Unrecognized RSA or RSASSA-PSS key algorithm name.");
        }
        int size = KeysBridge.findBitLength(key);
        if (size < 0) return; // https://github.com/jwtk/jjwt/issues/68
        if (size < MIN_KEY_BIT_LENGTH) {
            String id = getId();
            String section = id.startsWith("PS") ? "3.5" : "3.3";
            String msg = "The RSA " + keyType(signing) + " 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.  Consider using the Jwts.SIG." + id +
                    ".keyPair() builder to create a KeyPair guaranteed to be secure enough for " + id + ".  See " +
                    "https://tools.ietf.org/html/rfc7518#section-" + section + " for more information.";
            throw new WeakKeyException(msg);
        }
    }

    @Override
    protected byte[] doDigest(final SecureRequest<InputStream, PrivateKey> request) {
        return jca(request).withSignature(new CheckedFunction<Signature, byte[]>() {
            @Override
            public byte[] apply(Signature sig) throws Exception {
                if (algorithmParameterSpec != null) {
                    sig.setParameter(algorithmParameterSpec);
                }
                sig.initSign(request.getKey());
                return sign(sig, request.getPayload());
            }
        });
    }

    @Override

View on GitHub (pinned to fb71496164)