gchq/CyberChef · error · OperationError

Invalid secret. The input must be a valid base32 string (cha

Error message

Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).

What it means

Thrown by GenerateHOTP when the user-supplied secret cannot be parsed as a valid RFC 4648 base32 string. CyberChef decodes the input as UTF-8, trims it, uppercases it, and strips whitespace before handing it to OTPAuth.Secret.fromBase32(). If that call rejects the value (illegal characters, wrong padding, empty-after-trim edge cases), the catch block surfaces this generic OperationError. It is an expected user-input error, not an internal fault.

Source

Thrown at src/core/operations/GenerateHOTP.mjs:64

                "min": 0,
                "integer": true
            }
        ];
    }

    /**
     *
     */
    run(input, args) {
        const secretStr = new TextDecoder("utf-8").decode(input).trim();

        let secret;
        try {
            secret = secretStr ?
                OTPAuth.Secret.fromBase32(secretStr.toUpperCase().replace(/\s+/g, "")) :
                new OTPAuth.Secret();
        } catch {
            throw new OperationError("Invalid secret. The input must be a valid base32 string (characters A–Z and 2–7).");
        }

        const hotp = new OTPAuth.HOTP({
            issuer: "",
            label: args[0],
            algorithm: "SHA1",
            digits: args[1],
            counter: args[2],
            secret
        });

        const uri = hotp.toString();
        const code = hotp.generate();

        return `URI: ${uri}\n\nPassword: ${code}`;
    }
}

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Ensure the input contains only base32 alphabet characters A-Z and 2-7 (spaces are tolerated and stripped).
  2. Remove any '=' padding, dashes, or non-base32 symbols from the secret.
  3. If you have a hex or base64 secret, convert it to base32 first using the From Hex / From Base64 operations.

Example fix

// before (hex secret passed directly)
JBSWY3DPEHPK3PXP -> error if it contains '1','8','9','0'
// after
const clean = secret.toUpperCase().replace(/[^A-Z2-7]/g, "");
// feed only clean base32 to the operation
Defensive patterns

Strategy: validation

Validate before calling

const BASE32 = /^[A-Z2-7]+$/;
const cleaned = secretStr.toUpperCase().replace(/\s+/g, "");
if (secretStr && !BASE32.test(cleaned)) {
  // do not call the operation; surface a base32 error to the user
}

Type guard

function isValidBase32Secret(s) {
  if (!s) return true; // empty is allowed (random secret)
  return /^[A-Z2-7]+$/.test(s.toUpperCase().replace(/\s+/g, ""));
}

Try / catch

try {
  return OTPAuth.Secret.fromBase32(cleaned);
} catch {
  throw new OperationError("Invalid secret. Use base32 A-Z and 2-7.");
}

Prevention

When it happens

Trigger: Calling GenerateHOTP.run() with input containing characters outside A-Z and 2-7 (e.g. '0', '1', '8', '9', lowercase before uppercasing if non-ASCII present), or with malformed padding. An empty string does NOT trigger it — an empty secret produces a new random OTPAuth.Secret() instead.

Common situations: Pasting a TOTP/HOTP secret that includes spaces or dashes that survive the whitespace strip, copying a hex-encoded or base64 secret by mistake, or feeding a secret with '=' padding the library rejects.

Related errors


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