gchq/CyberChef · error · OperationError

Invalid key length: ${key.length} bytes. Salsa20 uses a key

Error message

Invalid key length: ${key.length} bytes.

Salsa20 uses a key of 16 or 32 bytes (128 or 256 bits).

What it means

Thrown by the Salsa20 operation when the decoded key is neither 16 nor 32 bytes. Salsa20 supports 128-bit (16-byte) or 256-bit (32-byte) keys only. The key is decoded from its toggle option (Hex/UTF8/Latin1/Base64) before the length check.

Source

Thrown at src/core/operations/Salsa20.mjs:80

                "value": ["Raw", "Hex"]
            }
        ];
    }

    /**
     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const key = Utils.convertToByteArray(args[0].string, args[0].option),
            nonceType = args[1].option,
            rounds = parseInt(args[3], 10),
            inputType = args[4],
            outputType = args[5];

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

Salsa20 uses a key of 16 or 32 bytes (128 or 256 bits).`);
        }

        let counter, nonce;
        if (nonceType === "Integer") {
            nonce = Utils.intToByteArray(parseInt(args[1].string, 10), 8, "little");
        } else {
            nonce = Utils.convertToByteArray(args[1].string, args[1].option);
            if (!(nonce.length === 8)) {
                throw new OperationError(`Invalid nonce length: ${nonce.length} bytes.

Salsa20 uses a nonce of 8 bytes (64 bits).`);
            }
        }
        counter = Utils.intToByteArray(args[2], 8, "little");

        const output = [];

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Provide a 16-byte or 32-byte key; for hex keys use the 'Hex' toggle so char count halves to bytes.
  2. Confirm the toggle matches the key's encoding.
  3. Remove trailing whitespace/newlines from the key.

Example fix

// before: 16 hex chars read as UTF8 -> 16 bytes (ok), but 64 hex chars -> 64 bytes (fails)
salsa20.run(pt, [{string:"<64 hex>", option:"UTF8"}, ...])
// after
salsa20.run(pt, [{string:"<64 hex>", option:"Hex"}, ...])
Defensive patterns

Strategy: validation

Validate before calling

const key = Utils.convertToByteArray(keyArg.string, keyArg.option);
if (key.length !== 16 && key.length !== 32) {
  throw new Error(`Salsa20 key must be 16 or 32 bytes, got ${key.length}. Check toggle.`);
}

Type guard

function isSalsa20KeyArg(arg) {
  const len = Utils.convertToByteArray(arg.string, arg.option).length;
  return len === 16 || len === 32;
}

Prevention

When it happens

Trigger: A key whose decoded byte length is not 16 or 32 — e.g. a 20-byte key, or a toggle mismatch turning a 32-char hex key into 32 UTF8 bytes (which happens to be valid) while a 16-char one becomes 16 bytes (also coincidentally valid), but a 24-char key or wrong toggle fails.

Common situations: Toggle set to UTF8 while the key is hex (or vice versa); using a ChaCha20 32-byte key with wrong toggle; blank key (0 bytes); truncated key.

Related errors


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