{"record":{"id":"f8bc2271fa430288","repo":"gchq/CyberChef","slug":"provided-key-is-not-a-private-key","errorCode":null,"errorMessage":"Provided key is not a private key.","messagePattern":"Provided key is not a private key\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ECDSASign.mjs","lineNumber":79,"sourceCode":"     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     */\n    run(input, args) {\n        const [keyPem, mdAlgo, outputFormat] = args;\n\n        if (keyPem.replace(\"-----BEGIN EC PRIVATE KEY-----\", \"\").length === 0) {\n            throw new OperationError(\"Please enter a private key.\");\n        }\n\n        const internalAlgorithmName = mdAlgo.replace(\"-\", \"\") + \"withECDSA\";\n        const sig = new r.KJUR.crypto.Signature({ alg: internalAlgorithmName });\n        const key = r.KEYUTIL.getKey(keyPem);\n        if (key.type !== \"EC\") {\n            throw new OperationError(\"Provided key is not an EC key.\");\n        }\n        if (!key.isPrivate) {\n            throw new OperationError(\"Provided key is not a private key.\");\n        }\n        sig.init(key);\n        const signatureASN1Hex = sig.signString(input);\n\n        let result;\n        switch (outputFormat) {\n            case \"ASN.1 HEX\":\n                result = signatureASN1Hex;\n                break;\n            case \"P1363 HEX\":\n                result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex);\n                break;\n            case \"JSON Web Signature\":\n                result = r.KJUR.crypto.ECDSA.asn1SigToConcatSig(signatureASN1Hex);\n                result = toBase64(fromHex(result), \"A-Za-z0-9-_\");  // base64url\n                break;\n            case \"Raw JSON\": {\n                const signatureRS = r.KJUR.crypto.ECDSA.parseSigHexInHexRS(signatureASN1Hex);","sourceCodeStart":61,"sourceCodeEnd":97,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ECDSASign.mjs#L61-L97","documentation":"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).","triggerScenarios":"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.","commonSituations":"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.","solutions":["Paste the EC PRIVATE key PEM (-----BEGIN EC PRIVATE KEY----- or -----BEGIN PRIVATE KEY----- with EC algorithm).","If you intend to verify, use ECDSA Verify with the public key instead.","Keep the private key secure and ensure the full private PEM is used for signing."],"exampleFix":"// before: EC public key (isPrivate === false)\nconst key = ecPublicKeyPem;\n// after: EC private key\nconst key = ecPrivateKeyPem; // key.isPrivate === true","handlingStrategy":"validation","validationCode":"import r from \"jsrsasign\";\nconst key = r.KEYUTIL.getKey(keyPem);\nif (key.type === \"EC\" && !key.isPrivate) throw new Error(\"provided EC key is public; signing needs the private key\");","typeGuard":"const isEcPrivateKey = (k) => k && k.type === \"EC\" && k.isPrivate === true;","tryCatchPattern":null,"preventionTips":["Keep public and private keys clearly labelled to avoid swapping them.","Confirm key.isPrivate before signing recipes."],"tags":["crypto","ecdsa","key-validation","jsrsasign","operation-error"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}