{"record":{"id":"612a0faed7b1c423","repo":"jwtk/jjwt","slug":"invalid-aes-key-length-bitsmsg-keybitlength","errorCode":null,"errorMessage":"Invalid AES key length: ${bitsMsg(keyBitLength)}. AES only supports 128, 192, or 256 bit keys.","messagePattern":"Invalid AES key length: (.+?)\\. AES only supports 128, 192, or 256 bit keys\\.","errorType":"validation","errorClass":"IllegalArgumentException","httpStatus":null,"severity":"error","filePath":"impl/src/main/java/io/jsonwebtoken/impl/security/AesAlgorithm.java","lineNumber":68,"sourceCode":"            \"requests that do not include initialization vectors. AES ciphertext without an IV is weak and \" +\n            \"susceptible to attack.\";\n\n    protected final int keyBitLength;\n    protected final int ivBitLength;\n    protected final int tagBitLength;\n    protected final boolean gcm;\n\n    /**\n     * Ensures {@code keyBitLength is a valid AES key length}\n     *\n     * @param keyBitLength the key length (in bits) to check\n     * @since 0.12.4\n     */\n    static void assertKeyBitLength(int keyBitLength) {\n        if (keyBitLength == 128 || keyBitLength == 192 || keyBitLength == 256) return; // valid\n        String msg = \"Invalid AES key length: \" + Bytes.bitsMsg(keyBitLength) + \". AES only supports \" +\n                \"128, 192, or 256 bit keys.\";\n        throw new IllegalArgumentException(msg);\n    }\n\n    static SecretKey keyFor(byte[] bytes) {\n        int bitlen = (int) Bytes.bitLength(bytes);\n        assertKeyBitLength(bitlen);\n        return new SecretKeySpec(bytes, KEY_ALG_NAME);\n    }\n\n    AesAlgorithm(String id, final String jcaTransformation, int keyBitLength) {\n        super(id, jcaTransformation);\n        assertKeyBitLength(keyBitLength);\n        this.keyBitLength = keyBitLength;\n        this.gcm = jcaTransformation.startsWith(\"AES/GCM\");\n        this.ivBitLength = jcaTransformation.equals(\"AESWrap\") ? 0 : (this.gcm ? GCM_IV_SIZE : BLOCK_SIZE);\n        // https://tools.ietf.org/html/rfc7518#section-5.2.3 through https://tools.ietf.org/html/rfc7518#section-5.3 :\n        this.tagBitLength = this.gcm ? BLOCK_SIZE : this.keyBitLength;\n    }\n","sourceCodeStart":50,"sourceCodeEnd":86,"githubUrl":"https://github.com/jwtk/jjwt/blob/fb71496164c71442d08adec4571d9616ed5e1b8d/impl/src/main/java/io/jsonwebtoken/impl/security/AesAlgorithm.java#L50-L86","documentation":"AesAlgorithm.assertKeyBitLength enforces AES-compliant key sizes: exactly 128, 192, or 256 bits. Any other length throws IllegalArgumentException with a human-readable bits message. It is called by keyFor and the constructor, so malformed AES key bytes are rejected early.","triggerScenarios":"Calling KeysBuilder/SecretKeySpec-style AES key creation with byte arrays whose bit length is not 128/192/256 (e.g. a 16-byte string plus newline = 136 bits, truncated base64, or a password used directly as key bytes).","commonSituations":"Using a raw password as an AES key; decoding base64 keys with whitespace; generating keys with a non-AES KeyGenerator; hand-truncating key material.","solutions":["Derive a proper AES key from a password with PBKDF2: SecretKeyFactory.getInstance('PBKDF2WithHmacSHA256') then pad/choose 256-bit output.","Generate keys with KeyGenerator.getInstance(\"AES\") initialized to 128/192/256 bits.","Check bytes.length * 8 is 128, 192, or 256 before calling keyFor.","Trim stray whitespace/newlines from encoded key strings before decoding."],"exampleFix":"// before\nSecretKey key = Keys.forAes(password.getBytes());\n// after\nKeyGenerator kg = KeyGenerator.getInstance(\"AES\");\nkg.init(256);\nSecretKey key = kg.generateKey();","handlingStrategy":"validation","validationCode":"if (bytes.length * 8 != 128 && bytes.length * 8 != 192 && bytes.length * 8 != 256) throw new IllegalArgumentException(\"AES key must be 128/192/256 bits, got \" + bytes.length * 8);","typeGuard":"boolean isAesKeyLength(byte[] b) { int bits = b.length * 8; return bits == 128 || bits == 192 || bits == 256; }","tryCatchPattern":"try { SecretKey k = Keys.forAes(bytes); }\ncatch (IllegalArgumentException e) { throw new ConfigException(\"Bad AES key material: \" + e.getMessage()); }","preventionTips":["Generate AES keys with KeyGenerator.getInstance(\"AES\").","Derive keys from passwords with PBKDF2, never raw passwords.","Strip whitespace before base64-decoding key material.","Assert key byte length in unit tests."],"tags":["aes","key-length","crypto","jjwt"],"backgroundTag":"invalid-argument-value","analyzedSha":"fb71496164c71442d08adec4571d9616ed5e1b8d","analyzedAt":"2026-09-09T00:33:09.982Z","contentChangedAt":"2026-09-09T00:33:09.982Z","schemaVersion":2},"datasetVersion":"2026-09-14T11:17:12.474Z"}