jwtk/jjwt · error · SecurityException
Unable to derive key
Error message
Unable to derive key
What it means
Thrown as a io.jsonwebtoken.SecurityException when PBES2 password-based key derivation fails. The library wraps any exception raised by the JCA SecretKeyFactory (e.g. PBKDF2WithHmacSHA*) used to stretch the caller-supplied Password into an encryption key. It indicates the password-to-key conversion step of a JWE could not be completed, not that the JWT itself is malformed.
Source
Thrown at impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java:93
return secretKeyFactory;
}
});
// pre-compute the salt so we don't spend time doing that on each iteration. Doesn't need to be random for a
// computation-only test:
final byte[] rfcSalt = alg.toRfcSalt(alg.generateInputSalt(null));
// ensure that the bare minimum steps are performed to hash, ensuring our time sampling pertains only to
// hashing and not ancillary steps needed to setup the hashing/derivation
return new KeyAlgorithm<Password, Password>() {
@Override
public KeyResult getEncryptionKey(KeyRequest<Password> request) throws SecurityException {
int iterations = request.getHeader().getPbes2Count();
char[] password = request.getKey().getPassword();
try {
alg.deriveKey(factory, password, rfcSalt, iterations);
} catch (Exception e) {
throw new SecurityException("Unable to derive key", e);
}
return null;
}
@Override
public SecretKey getDecryptionKey(DecryptionKeyRequest<Password> request) throws SecurityException {
throw new UnsupportedOperationException("Not intended to be called.");
}
@Override
public String getId() {
return alg.getId();
}
};
}
private static char randomChar() {
return (char) Randoms.secureRandom().nextInt(Character.MAX_VALUE);View on GitHub (pinned to fb71496164)
Solutions
- Verify the JRE supports the PBKDF2 algorithm (e.g. SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256")) and register a provider if not.
- Check that the Password passed to Jwts.builder().encryptWith(password, ...) / parser decryptWith has valid non-empty characters.
- Inspect the wrapped cause (e.getCause()) to identify the actual JCA failure and fix accordingly.
- If on a FIPS or restricted JVM, configure the security policy to permit the required PBKDF2 transformation.
Example fix
// before (may throw on JREs without PBKDF2)
Jwts.parser().decryptWith(password).build().parseEncryptedClaims(token);
// after
try {
Jwts.parser().decryptWith(password).build().parseEncryptedClaims(token);
} catch (SecurityException e) {
logger.error("Key derivation failed: " + e.getCause(), e);
} Defensive patterns
Strategy: try-catch
Validate before calling
try {
javax.crypto.SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
} catch (NoSuchAlgorithmException e) {
throw new IllegalStateException("JRE lacks PBKDF2 support required for PBES2 JWEs");
} Type guard
// char[] password != null && password.length > 0 before encryptWith/decryptWith boolean usablePassword = password != null && password.length > 0;
Try / catch
try {
Jwts.parser().decryptWith(password).build().parseEncryptedClaims(token);
} catch (SecurityException e) {
// inspect e.getCause() for the JCA failure
} Prevention
- Confirm the target JRE supports PBKDF2 algorithms before shipping PBES2 flows
- Never pass null/empty Password instances
- Keep all jjwt artifacts on the same version
- Test crypto flows on all target JVMs (FIPS, IBM, SAP)
When it happens
Trigger: Decrypting or encrypting a JWE with a Password key and PBES2 headers (pbes2Count from the header) when the underlying JCA provider cannot run the requested PBKDF2 algorithm, the password/char[] is unusable, or the JRE lacks the algorithm (e.g. older IBM JREs or hardened crypto policies).
Common situations: Running on a JRE without PBKDF2WithHmacSHA256 support, unrestricted-algorithms policies disabled, using a Password with null/blank characters, or provider misconfiguration in restricted environments (FIPS).
Related errors
- [JWA RFC 7518, Section 4.8.1.2](https://www.rfc-editor.org/r
- Unexpected content JWE.
- Unexpected Claims JWE.
- PrivateKeys may not be used to encrypt data. PublicKeys are
- Payload encoding may not be disabled for s, only JWSs.
AI-assisted analysis of jwtk/jjwt@fb71496164 (2026-09-09).
Data as JSON: /api/errors/ad2378e8b1094710.
Report an issue: GitHub.