gchq/CyberChef · error · OperationError

Invalid key length: ${key.length} bytes SM4 uses a key leng

Error message

Invalid key length: ${key.length} bytes

SM4 uses a key length of 16 bytes (128 bits).

What it means

Thrown by SM4 Decrypt when the key, after conversion via Utils.convertToByteArray, is not exactly 16 bytes. SM4 is a 128-bit block cipher requiring a 128-bit (16-byte) key. The key is decoded according to its toggle option (Hex, UTF8, Latin1, Base64) before the length check.

Source

Thrown at src/core/operations/SM4Decrypt.mjs:72

                "name": "Output",
                "type": "option",
                "value": ["Hex", "Raw"]
            }
        ];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const key = Utils.convertToByteArray(args[0].string, args[0].option),
            iv = Utils.convertToByteArray(args[1].string, args[1].option),
            [,, mode, inputType, outputType] = args;

        if (key.length !== 16)
            throw new OperationError(`Invalid key length: ${key.length} bytes

SM4 uses a key length of 16 bytes (128 bits).`);
        if (iv.length !== 16 && !mode.startsWith("ECB"))
            throw new OperationError(`Invalid IV length: ${iv.length} bytes

SM4 uses an IV length of 16 bytes (128 bits).
Make sure you have specified the type correctly (e.g. Hex vs UTF8).`);

        input = Utils.convertToByteArray(input, inputType);
        const output = decryptSM4(input, key, iv, mode.substring(0, 3), mode.endsWith("NoPadding"));
        return outputType === "Hex" ? toHex(output) : Utils.byteArrayToUtf8(output);
    }

}

export default SM4Decrypt;

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Ensure the decoded key is exactly 16 bytes; if the key is a 32-char hex string, set the toggle to 'Hex'.
  2. Confirm the toggle option matches the key's actual encoding (Hex vs UTF8 vs Base64).
  3. Remove trailing whitespace/newlines from the key field.

Example fix

// before: 32 hex chars interpreted as UTF8 -> 32 bytes
sm4Decrypt.run(ct, [{string:"0123456789abcdef0123456789abcdef", option:"UTF8"}, ...])
// after: toggle to Hex -> 16 bytes
sm4Decrypt.run(ct, [{string:"0123456789abcdef0123456789abcdef", option:"Hex"}, ...])
Defensive patterns

Strategy: validation

Validate before calling

import Utils from "src/core/Utils.mjs";
const key = Utils.convertToByteArray(keyArg.string, keyArg.option);
if (key.length !== 16) {
  throw new Error(`SM4 key must decode to 16 bytes, got ${key.length}. Check Hex vs UTF8 toggle.`);
}

Type guard

function isSm4KeyArg(arg) {
  const bytes = Utils.convertToByteArray(arg.string, arg.option);
  return bytes.length === 16;
}

Prevention

When it happens

Trigger: Supplying a key whose decoded byte length differs from 16 — e.g. 15 or 17 bytes. A common cause is a format mismatch: a 32-char hex key is 16 bytes, but if the toggle is set to UTF8 that same 32-char string becomes 32 bytes and fails.

Common situations: Key toggle set to UTF8 while the key is actually hex (or vice versa); leaving the key blank (0 bytes); pasting a 24-byte AES-192 key by mistake; trailing newlines inflating UTF8 byte count.

Related errors


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