keycloak/keycloak · error · IllegalStateException
Length of aes key should be {expectedAesKeyLength}, but was
Error message
Length of aes key should be {expectedAesKeyLength}, but was {length} What it means
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.
Source
Thrown at core/src/main/java/org/keycloak/jose/jwe/enc/AesCbcHmacShaEncryptionProvider.java:66
public void encodeJwe(JWE jwe) throws IOException, GeneralSecurityException {
byte[] contentBytes = jwe.getContent();
byte[] initializationVector = JWEUtils.generateSecret(16);
Key aesKey = jwe.getKeyStorage().getCEKKey(JWEKeyStorage.KeyUse.ENCRYPTION, false);
if (aesKey == null) {
throw new IllegalArgumentException("AES CEK key not present");
}
Key hmacShaKey = jwe.getKeyStorage().getCEKKey(JWEKeyStorage.KeyUse.SIGNATURE, false);
if (hmacShaKey == null) {
throw new IllegalArgumentException("HMAC CEK key not present");
}
int expectedAesKeyLength = getExpectedAesKeyLength();
if (expectedAesKeyLength != aesKey.getEncoded().length) {
throw new IllegalStateException("Length of aes key should be " + expectedAesKeyLength +", but was " + aesKey.getEncoded().length);
}
byte[] cipherBytes = encryptBytes(contentBytes, initializationVector, aesKey);
byte[] aad = jwe.getBase64Header().getBytes(StandardCharsets.UTF_8);
byte[] authenticationTag = computeAuthenticationTag(aad, initializationVector, cipherBytes, hmacShaKey);
jwe.setEncryptedContentInfo(initializationVector, cipherBytes, authenticationTag);
}
@Override
public void verifyAndDecodeJwe(JWE jwe) throws IOException, GeneralSecurityException {
Key aesKey = jwe.getKeyStorage().getCEKKey(JWEKeyStorage.KeyUse.ENCRYPTION, false);
if (aesKey == null) {
throw new IllegalArgumentException("AES CEK key not present");
}
View on GitHub (pinned to 66c7e15a37)
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().
Example fix
// before // using a 128-bit key with A256CBC-HS512 jwe.getKeyStorage().setCEKKey(new SecretKeySpec(sixteenBytes, "AES"), JWEKeyStorage.KeyUse.ENCRYPTION); // after // A256CBC-HS512 expects a 32-byte AES key jwe.getKeyStorage().setCEKKey(new SecretKeySpec(thirtyTwoBytes, "AES"), JWEKeyStorage.KeyUse.ENCRYPTION);
Defensive patterns
Strategy: validation
Validate before calling
public static void validateAesKeyLength(Key aesKey, int expected) {
if (aesKey == null || aesKey.getEncoded().length != expected) {
throw new IllegalStateException("AES key must be " + expected + " bytes");
}
} Try / catch
try {
provider.encodeJwe(jwe);
} catch (IllegalStateException e) {
if (e.getMessage().contains("Length of aes key")) {
throw new ConfigurationException("AES key length does not match the enc algorithm", e);
}
throw e;
} Prevention
- 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().
When it happens
Trigger: 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).
Common situations: 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.
Related errors
- AES CEK key not present
- HMAC CEK key not present
- Header must be set
- Content must be set
- No provider for alg '{algorithm}'
AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14).
Data as JSON: /api/errors/a69ab83ee63afbb4.
Report an issue: GitHub.