{"record":{"id":"a69ab83ee63afbb4","repo":"keycloak/keycloak","slug":"length-of-aes-key-should-be-expectedaeskeylength","errorCode":null,"errorMessage":"Length of aes key should be {expectedAesKeyLength}, but was {length}","messagePattern":"Length of aes key should be (.+?), but was (.+?)","errorType":"exception","errorClass":"IllegalStateException","httpStatus":null,"severity":"error","filePath":"core/src/main/java/org/keycloak/jose/jwe/enc/AesCbcHmacShaEncryptionProvider.java","lineNumber":66,"sourceCode":"    public void encodeJwe(JWE jwe) throws IOException, GeneralSecurityException {\n\n        byte[] contentBytes = jwe.getContent();\n\n        byte[] initializationVector = JWEUtils.generateSecret(16);\n\n        Key aesKey = jwe.getKeyStorage().getCEKKey(JWEKeyStorage.KeyUse.ENCRYPTION, false);\n        if (aesKey == null) {\n            throw new IllegalArgumentException(\"AES CEK key not present\");\n        }\n\n        Key hmacShaKey = jwe.getKeyStorage().getCEKKey(JWEKeyStorage.KeyUse.SIGNATURE, false);\n        if (hmacShaKey == null) {\n            throw new IllegalArgumentException(\"HMAC CEK key not present\");\n        }\n\n        int expectedAesKeyLength = getExpectedAesKeyLength();\n        if (expectedAesKeyLength != aesKey.getEncoded().length) {\n            throw new IllegalStateException(\"Length of aes key should be \" + expectedAesKeyLength +\", but was \" + aesKey.getEncoded().length);\n        }\n\n        byte[] cipherBytes = encryptBytes(contentBytes, initializationVector, aesKey);\n\n        byte[] aad = jwe.getBase64Header().getBytes(StandardCharsets.UTF_8);\n        byte[] authenticationTag = computeAuthenticationTag(aad, initializationVector, cipherBytes, hmacShaKey);\n\n        jwe.setEncryptedContentInfo(initializationVector, cipherBytes, authenticationTag);\n    }\n\n\n    @Override\n    public void verifyAndDecodeJwe(JWE jwe) throws IOException, GeneralSecurityException {\n        Key aesKey = jwe.getKeyStorage().getCEKKey(JWEKeyStorage.KeyUse.ENCRYPTION, false);\n        if (aesKey == null) {\n            throw new IllegalArgumentException(\"AES CEK key not present\");\n        }\n","sourceCodeStart":48,"sourceCodeEnd":84,"githubUrl":"https://github.com/keycloak/keycloak/blob/66c7e15a3788de7764f07dd2558275a02770e16d/core/src/main/java/org/keycloak/jose/jwe/enc/AesCbcHmacShaEncryptionProvider.java#L48-L84","documentation":"Thrown by AesCbcHmacShaEncryptionProvider when the AES key's encoded byte length does not match the algorithm's expected length: 16 for A128CBC-HS256, 24 for A192CBC-HS384, 32 for A256CBC-HS512. This guards against a CEK that was split incorrectly or a manually-supplied key sized for a different algorithm.","triggerScenarios":"The CEK was deserialized with a total length that does not halve into the expected AES key size, or a caller set an AES key directly whose length mismatches the selected enc (e.g. a 16-byte key with A256CBC-HS512 which expects 32).","commonSituations":"Mismatch between the enc header and the actual CEK material (e.g. the producer used A128 but the consumer configured A256), or a custom key-derivation step that produced the wrong key size.","solutions":["Match the CEK/key length to the enc algorithm: 32-byte total CEK for A128CBC-HS256, 48 for A192CBC-HS384, 64 for A256CBC-HS512 (half is AES, half is HMAC).","Confirm the producer and consumer agree on the enc value.","When setting keys manually, use SecretKeySpec sized exactly to getExpectedAesKeyLength()."],"exampleFix":"// before\n// using a 128-bit key with A256CBC-HS512\njwe.getKeyStorage().setCEKKey(new SecretKeySpec(sixteenBytes, \"AES\"), JWEKeyStorage.KeyUse.ENCRYPTION);\n\n// after\n// A256CBC-HS512 expects a 32-byte AES key\njwe.getKeyStorage().setCEKKey(new SecretKeySpec(thirtyTwoBytes, \"AES\"), JWEKeyStorage.KeyUse.ENCRYPTION);","handlingStrategy":"validation","validationCode":"public static void validateAesKeyLength(Key aesKey, int expected) {\n    if (aesKey == null || aesKey.getEncoded().length != expected) {\n        throw new IllegalStateException(\"AES key must be \" + expected + \" bytes\");\n    }\n}","typeGuard":null,"tryCatchPattern":"try {\n    provider.encodeJwe(jwe);\n} catch (IllegalStateException e) {\n    if (e.getMessage().contains(\"Length of aes key\")) {\n        throw new ConfigurationException(\"AES key length does not match the enc algorithm\", e);\n    }\n    throw e;\n}","preventionTips":["Match CEK/key length to the enc algorithm (AES half: 16/24/32 bytes for A128/A192/A256).","Ensure producer and consumer agree on the enc value so CEK sizes line up.","When constructing SecretKeySpec manually, size it to getExpectedAesKeyLength()."],"tags":["jose","jwe","encryption","aes","key-management","keycloak"],"backgroundTag":null,"analyzedSha":"66c7e15a3788de7764f07dd2558275a02770e16d","analyzedAt":"2026-08-14T01:36:42.651Z","schemaVersion":2},"datasetVersion":"2026-08-14T05:17:29.042Z"}