{"record":{"id":"ad2378e8b1094710","repo":"jwtk/jjwt","slug":"unable-to-derive-key","errorCode":null,"errorMessage":"Unable to derive key","messagePattern":"Unable to derive key","errorType":"exception","errorClass":"SecurityException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java","lineNumber":93,"sourceCode":"                return secretKeyFactory;\n            }\n        });\n\n        // pre-compute the salt so we don't spend time doing that on each iteration.  Doesn't need to be random for a\n        // computation-only test:\n        final byte[] rfcSalt = alg.toRfcSalt(alg.generateInputSalt(null));\n\n        // ensure that the bare minimum steps are performed to hash, ensuring our time sampling pertains only to\n        // hashing and not ancillary steps needed to setup the hashing/derivation\n        return new KeyAlgorithm<Password, Password>() {\n            @Override\n            public KeyResult getEncryptionKey(KeyRequest<Password> request) throws SecurityException {\n                int iterations = request.getHeader().getPbes2Count();\n                char[] password = request.getKey().getPassword();\n                try {\n                    alg.deriveKey(factory, password, rfcSalt, iterations);\n                } catch (Exception e) {\n                    throw new SecurityException(\"Unable to derive key\", e);\n                }\n                return null;\n            }\n\n            @Override\n            public SecretKey getDecryptionKey(DecryptionKeyRequest<Password> request) throws SecurityException {\n                throw new UnsupportedOperationException(\"Not intended to be called.\");\n            }\n\n            @Override\n            public String getId() {\n                return alg.getId();\n            }\n        };\n    }\n\n    private static char randomChar() {\n        return (char) Randoms.secureRandom().nextInt(Character.MAX_VALUE);","sourceCodeStart":75,"sourceCodeEnd":111,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/StandardKeyAlgorithms.java#L75-L111","documentation":"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.","triggerScenarios":"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).","commonSituations":"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).","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."],"exampleFix":"// before (may throw on JREs without PBKDF2)\nJwts.parser().decryptWith(password).build().parseEncryptedClaims(token);\n// after\ntry {\n    Jwts.parser().decryptWith(password).build().parseEncryptedClaims(token);\n} catch (SecurityException e) {\n    logger.error(\"Key derivation failed: \" + e.getCause(), e);\n}","handlingStrategy":"try-catch","validationCode":"try {\n    javax.crypto.SecretKeyFactory.getInstance(\"PBKDF2WithHmacSHA256\");\n} catch (NoSuchAlgorithmException e) {\n    throw new IllegalStateException(\"JRE lacks PBKDF2 support required for PBES2 JWEs\");\n}","typeGuard":"// char[] password != null && password.length > 0 before encryptWith/decryptWith\nboolean usablePassword = password != null && password.length > 0;","tryCatchPattern":"try {\n    Jwts.parser().decryptWith(password).build().parseEncryptedClaims(token);\n} catch (SecurityException e) {\n    // inspect e.getCause() for the JCA failure\n}","preventionTips":["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)"],"tags":["jwt","jwe","key-derivation","security"],"backgroundTag":"key-derivation-failed","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T05:17:10.506Z"}