gchq/CyberChef · error · OperationError

Invalid key length: ${key.length} bytes The following algor

Error message

Invalid key length: ${key.length} bytes

The following algorithms will be used based on the size of the key:
  16 bytes = AES-128
  24 bytes = AES-192
  32 bytes = AES-256

What it means

AES only accepts key sizes of 16, 24, or 32 bytes (AES-128/192/256 respectively). After converting the key argument to a byte string, AESDecrypt checks key.length against [16, 24, 32] and throws this OperationError if it is absent. This is enforced before any decryption begins.

Source

Thrown at src/core/operations/AESDecrypt.mjs:152

     *
     * @throws {OperationError} if cannot decrypt input or invalid key length
     */
    run(input, args) {
        let iv;

        const key = Utils.convertToByteString(args[0].string, args[0].option),
            ivLength = args[2],
            mode = args[3].split("/")[0],
            noPadding = args[3].endsWith("NoPadding"),
            inputType = args[4],
            outputType = args[5],
            gcmTag = Utils.convertToByteString(args[6].string, args[6].option),
            aad = Utils.convertToByteString(args[7].string, args[7].option),
            ivFromInput = args[8];


        if ([16, 24, 32].indexOf(key.length) < 0) {
            throw new OperationError(`Invalid key length: ${key.length} bytes

The following algorithms will be used based on the size of the key:
  16 bytes = AES-128
  24 bytes = AES-192
  32 bytes = AES-256`);
        }

        input = Utils.convertToByteString(input, inputType);

        if (ivFromInput !== "Off") {
            if (input.length <= ivLength) {
                throw new OperationError(`Input is too short to contain an IV of ${ivLength} bytes.`);
            }

            if (ivFromInput === "From start") {
                iv = input.substr(0, ivLength);
                input = input.substr(ivLength);
            } else {

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Verify the Key Format option matches the bytes: select Hex for hex-encoded keys, Base64 for base64, UTF8 only for raw text.
  2. Compute the exact byte length you expect (16/24/32) and confirm the input produces it.
  3. If using a passphrase, derive the key with a KDF (PBKDF2/EVP_BytesToKey) so the output is exactly 16/24/32 bytes.
  4. Pad with zeros or hash (SHA-256 → 32 bytes) to reach a valid length only if that matches how the ciphertext was produced.

Example fix

// before: key "000102030405060708090a0b0c0d0e0f" with format UTF8 → 32 bytes (AES-256) when AES-128 intended
// after: set Key Format to "Hex" so the same string → 16 bytes (AES-128)
Defensive patterns

Strategy: validation

Validate before calling

function validateAesKey(keyBytes) {
  if (![16, 24, 32].includes(keyBytes.length)) {
    throw new Error(`Key must be 16/24/32 bytes, got ${keyBytes.length}`);
  }
}

Type guard

function isAesKey(bytes) {
  return bytes instanceof Uint8Array && [16, 24, 32].includes(bytes.length);
}

Try / catch

try { decryptAES(...); } catch (e) { if (/Invalid key length/.test(e.message)) {/* fix key format */} else throw e; }

Prevention

When it happens

Trigger: The key converted via Utils.convertToByteString(args[0].string, args[0].option) yields a length not equal to 16, 24, or 32. Common causes: the key was entered as a 16-char ASCII passphrase but interpreted as Hex (giving 8 bytes), a 32-char hex string interpreted as UTF8 (giving 32 bytes instead of 16), or an empty/short key.

Common situations: Key encoding option (UTF8 / Hex / Base64) does not match the actual format of the pasted key; a human-memorable passphrase is used directly as an AES key instead of being run through a KDF; key was truncated during copy-paste; mismatch between the key format used at encryption time and at decryption time.

Related errors


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/1b35ea6a0675e494. Report an issue: GitHub.