{"record":{"id":"5f9b69cb4b88dc85","repo":"gchq/CyberChef","slug":"please-enter-a-public-key","errorCode":null,"errorMessage":"Please enter a public key.","messagePattern":"Please enter a public key\\.","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/ECDSAVerify.mjs","lineNumber":82,"sourceCode":"            {\n                name: \"Message format\",\n                type: \"option\",\n                value: [\"Raw\", \"Hex\", \"Base64\"]\n            }\n        ];\n    }\n\n    /**\n     * @param {string} input\n     * @param {Object[]} args\n     * @returns {string}\n     */\n    run(input, args) {\n        let inputFormat = args[0];\n        const [, mdAlgo, keyPem, msg, msgFormat] = args;\n\n        if (keyPem.replace(\"-----BEGIN PUBLIC KEY-----\", \"\").length === 0) {\n            throw new OperationError(\"Please enter a public key.\");\n        }\n\n        // detect input format\n        let inputJson;\n        if (inputFormat === \"Auto\") {\n            try {\n                inputJson = JSON.parse(input);\n                if (typeof(inputJson) === \"object\") {\n                    inputFormat = \"Raw JSON\";\n                }\n            } catch {}\n        }\n\n        if (inputFormat === \"Auto\") {\n            const hexRegex = /^[a-f\\d]{2,}$/gi;\n            if (hexRegex.test(input)) {\n                if (input.substring(0, 2) === \"30\" && r.ASN1HEX.isASN1HEX(input)) {\n                    inputFormat = \"ASN.1 HEX\";","sourceCodeStart":64,"sourceCodeEnd":100,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/ECDSAVerify.mjs#L64-L100","documentation":"Thrown in ECDSAVerify.run when keyPem.replace('-----BEGIN PUBLIC KEY-----', '').length === 0. Exactly mirroring ECDSASign's placeholder guard, the operation's default public-key text is the header line alone; this catches the user who left the field at the placeholder or pasted only the header. It fires before signature format detection, so it is a key-presence guard, not a format check.","triggerScenarios":"The 'Public Key (PEM)' field still equals '-----BEGIN PUBLIC KEY-----' with nothing after, or holds only that header line.","commonSituations":"Default placeholder never replaced; a key missing the base64 body and END line; a recipe saved before the key was supplied.","solutions":["Paste a full EC public key PEM (-----BEGIN PUBLIC KEY----- ...base64... -----END PUBLIC KEY-----).","Extract the public key from a certificate with openssl if needed.","Ensure the full PEM text (header, body, footer) is saved in any shared recipe."],"exampleFix":"// before (placeholder only)\nconst key = '-----BEGIN PUBLIC KEY-----';\n// after\nconst key = '-----BEGIN PUBLIC KEY-----\\nMFkw...full base64...\\n-----END PUBLIC KEY-----';","handlingStrategy":"validation","validationCode":"function hasPemBody(pem, header) {\n  const after = pem.replace(header, \"\");\n  return after.trim().length > 0 && pem.includes(header.replace(\"BEGIN\", \"END\"));\n}\nif (!hasPemBody(keyPem, \"-----BEGIN PUBLIC KEY-----\")) throw new Error(\"paste a full EC public key\");","typeGuard":"const looksLikePublicKey = (p) => /-----BEGIN PUBLIC KEY-----[\\s\\S]+-----END PUBLIC KEY-----/.test(p);","tryCatchPattern":null,"preventionTips":["Always replace the placeholder header with a complete PEM (header+body+footer).","Validate the PEM has a body and END line before saving the recipe."],"tags":["crypto","ecdsa","key-validation","operation-error"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}