gchq/CyberChef · error · OperationError

Provided key is not a private key.

Error message

Provided key is not a private key.

What it means

Thrown in ECDSASign.run when the parsed EC key has !key.isPrivate. jsrsasign EC keys carry an isPrivate boolean; signing needs the private half. A public EC key parses fine (key.type === 'EC' passes the previous guard) but isPrivate is false, triggering this check before sig.init(key).

Source

Thrown at src/core/operations/ECDSASign.mjs:79

     * @param {string} input
     * @param {Object[]} args
     * @returns {string}
     */
    run(input, args) {
        const [keyPem, mdAlgo, outputFormat] = args;

        if (keyPem.replace("-----BEGIN EC PRIVATE KEY-----", "").length === 0) {
            throw new OperationError("Please enter a private key.");
        }

        const internalAlgorithmName = mdAlgo.replace("-", "") + "withECDSA";
        const sig = new r.KJUR.crypto.Signature({ alg: internalAlgorithmName });
        const key = r.KEYUTIL.getKey(keyPem);
        if (key.type !== "EC") {
            throw new OperationError("Provided key is not an EC key.");
        }
        if (!key.isPrivate) {
            throw new OperationError("Provided key is not a private key.");
        }
        sig.init(key);
        const signatureASN1Hex = sig.signString(input);

        let result;
        switch (outputFormat) {
            case "ASN.1 HEX":
                result = signatureASN1Hex;
                break;
            case "P1363 HEX":
                result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex);
                break;
            case "JSON Web Signature":
                result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex);
                result = toBase64(fromHex(result), "A-Za-z0-9-_");  // base64url
                break;
            case "Raw JSON": {
                const signatureRS = r.KJUR.crypto.ECDSA.parseSigHexInHexRS(signatureASN1Hex);

View on GitHub (pinned to 4290ea7539)

Solutions

  1. Paste the EC PRIVATE key PEM (-----BEGIN EC PRIVATE KEY----- or -----BEGIN PRIVATE KEY----- with EC algorithm).
  2. If you intend to verify, use ECDSA Verify with the public key instead.
  3. Keep the private key secure and ensure the full private PEM is used for signing.

Example fix

// before: EC public key (isPrivate === false)
const key = ecPublicKeyPem;
// after: EC private key
const key = ecPrivateKeyPem; // key.isPrivate === true
Defensive patterns

Strategy: validation

Validate before calling

import r from "jsrsasign";
const key = r.KEYUTIL.getKey(keyPem);
if (key.type === "EC" && !key.isPrivate) throw new Error("provided EC key is public; signing needs the private key");

Type guard

const isEcPrivateKey = (k) => k && k.type === "EC" && k.isPrivate === true;

Prevention

When it happens

Trigger: The user pasted an EC public key (-----BEGIN PUBLIC KEY-----) into the private-key field. KEYUTIL.getKey parses it, key.type is 'EC', but it is the public component, so signing is impossible.

Common situations: Mixing up public and private keys; pasting the recipient's public key when you meant to sign with your private key; extracting only the public key from a certificate.

Related errors


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