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 GenerateTOTP when the user-supplied secret cannot be parsed as a valid RFC 4648 base32 string. Identical handling to GenerateHOTP: input is UTF-8 decoded, trimmed, uppercased, whitespace-stripped, then passed to OTPAuth.Secret.fromBase32(). If that throws, this OperationError surfaces. Empty input yields a fresh random secret and does not trigger the error.

Source

Thrown at src/core/operations/GenerateTOTP.mjs:70

                "min": 1,
                "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 totp = new OTPAuth.TOTP({
            issuer: "",
            label: args[0],
            algorithm: "SHA1",
            digits: args[1],
            period: args[3],
            epoch: args[2] * 1000, // Convert seconds to milliseconds
            secret
        });

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

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

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Ensure the input contains only A-Z and 2-7 (spaces are stripped).
  2. Convert hex/base64 secrets to base32 before input.
  3. Remove '=' padding and dashes.

Example fix

// before
input = "JBSWY3DPEHPK3PXP=="; // padding may be rejected
// after
input = "JBSWY3DPEHPK3PXP";
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;
  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 GenerateTOTP.run() with input containing non-base32 characters (0, 1, 8, 9, or symbols beyond whitespace), or malformed padding.

Common situations: Pasting a secret copied with formatting artifacts, or supplying a hex/base64 secret directly.

Related errors


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