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

  1. 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).
  2. Confirm the producer and consumer agree on the enc value.
  3. 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

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


AI-assisted analysis of keycloak/keycloak@66c7e15a37 (2026-08-14). Data as JSON: /api/errors/a69ab83ee63afbb4. Report an issue: GitHub.