{"record":{"id":"5876457dbb1607f5","repo":"jwtk/jjwt","slug":"jwa-rfc-7518-section-4-8-1-2-https-www-rfc-ed","errorCode":null,"errorMessage":"[JWA RFC 7518, Section 4.8.1.2](https://www.rfc-editor.org/rfc/rfc7518.html#section-4.8.1.2) recommends password-based-encryption iterations be greater than or equal to 1000. Provided: ${iterations}","messagePattern":"\\[JWA RFC 7518, Section 4\\.8\\.1\\.2\\]\\(https://www\\.rfc-editor\\.org/rfc/rfc7518\\.html#section-4\\.8\\.1\\.2\\) recommends password-based-encryption iterations be greater than or equal to 1000\\. Provided: (.+?)","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithm.java","lineNumber":86,"sourceCode":"        // new byte array indices to 0x00, meaning the last one will be our zero delimiter:\n        byte[] output = new byte[bytes.length + 1];\n        System.arraycopy(bytes, 0, output, 0, bytes.length);\n        return output;\n    }\n\n    private static int hashBitLength(int keyBitLength) {\n        return keyBitLength * 2;\n    }\n\n    private static String idFor(int hashBitLength, KeyAlgorithm<SecretKey, SecretKey> wrapAlg) {\n        Assert.notNull(wrapAlg, \"wrapAlg argument cannot be null.\");\n        return \"PBES2-HS\" + hashBitLength + \"+\" + wrapAlg.getId();\n    }\n\n    public static int assertIterations(int iterations) {\n        if (iterations < MIN_RECOMMENDED_ITERATIONS) {\n            String msg = MIN_ITERATIONS_MSG_PREFIX + iterations;\n            throw new IllegalArgumentException(msg);\n        }\n        return iterations;\n    }\n\n    public Pbes2HsAkwAlgorithm(int keyBitLength) {\n        this(hashBitLength(keyBitLength), new AesWrapKeyAlgorithm(keyBitLength));\n    }\n\n    protected Pbes2HsAkwAlgorithm(int hashBitLength, KeyAlgorithm<SecretKey, SecretKey> wrapAlg) {\n        super(idFor(hashBitLength, wrapAlg), \"PBKDF2WithHmacSHA\" + hashBitLength);\n        this.wrapAlg = wrapAlg; // no need to assert non-null due to 'idFor' implementation above\n\n        // There's some white box knowledge here: there is no need to assert the value of hashBitLength\n        // because that is done implicitly in the constructor when instantiating AesWrapKeyAlgorithm. See that class's\n        // implementation to see the assertion:\n        this.HASH_BYTE_LENGTH = hashBitLength / Byte.SIZE;\n\n        // If the JwtBuilder caller doesn't specify an iteration count, fall back to OWASP best-practice recommendations","sourceCodeStart":68,"sourceCodeEnd":104,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/Pbes2HsAkwAlgorithm.java#L68-L104","documentation":"RFC 7518 Section 4.8.1.2 recommends PBES2 password-based encryption use at least 1000 iterations. Pbes2HsAkwAlgorithm.assertIterations enforces this minimum and throws IllegalArgumentException for lower values (MIN_RECOMMENDED_ITERATIONS = 1000).","triggerScenarios":"Calling iterations(n) or otherwise configuring a PBES2 JWE algorithm with a p2c/iteration count below 1000, either programmatically or via the 'p2c' header value when building.","commonSituations":"Copying example code with small iteration counts, tuning iterations down for speed in tests, or generating headers with p2c values from older configs.","solutions":["Increase the iteration count to at least 1000 (higher, e.g. 100000+, is better for security).","Wrap configuration in try-catch for IllegalArgumentException when accepting user-provided iteration counts.","Set iterations via the algorithm builder's iterations() method with a validated constant."],"exampleFix":"// before\nPbes2HsAkwAlgorithm alg = new Pbes2HsAkwAlgorithm(128).iterations(10);\n// after\nPbes2HsAkwAlgorithm alg = new Pbes2HsAkwAlgorithm(128).iterations(1000);","handlingStrategy":"validation","validationCode":"if (iterations < 1000) {\n    throw new IllegalArgumentException(\"p2c must be >= 1000 per RFC 7518 4.8.1.2\");\n}","typeGuard":null,"tryCatchPattern":"try {\n    alg.iterations(n);\n} catch (IllegalArgumentException e) {\n    // below recommended minimum: raise n\n}","preventionTips":["Use >= 1000 iterations (more is safer)","Never accept unvalidated user-provided p2c values","Store iteration counts as security-reviewed constants"],"tags":["jwt","jwe","pbes2","security"],"backgroundTag":"argument-out-of-range","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"}