{"record":{"id":"54d80f192ddd26dd","repo":"gchq/CyberChef","slug":"couldn-t-sign-message-err-54d80f","errorCode":null,"errorMessage":"Couldn't sign message: ${err}","messagePattern":"Couldn't sign message: (.+?)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/PGPSign.mjs","lineNumber":75,"sourceCode":"     *\n     * @throws {OperationError} if failed private key import or failed encryption\n     */\n    async run(input, args) {\n        const message = input,\n            [privateKey, passphrase] = args;\n        let signedMessage;\n\n        if (!privateKey) throw new OperationError(\"Enter the private key of the signer.\");\n        const privKey = await importPrivateKey(privateKey, passphrase);\n\n        try {\n            signedMessage = await promisify(kbpgp.box)({\n                \"msg\": message,\n                \"sign_with\": privKey,\n                \"asp\": ASP\n            });\n        } catch (err) {\n            throw new OperationError(`Couldn't sign message: ${err}`);\n        }\n\n        return signedMessage;\n    }\n\n}\n\nexport default PGPSign;\n","sourceCodeStart":57,"sourceCodeEnd":84,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/PGPSign.mjs#L57-L84","documentation":"Catch-all around kbpgp.box with sign_with only (no encryption) in PGPSign.run. The private key imported and unlocked fine, but the sign-only box call failed. The appended err holds the kbpgp cause.","triggerScenarios":"Private key has no signing capability/subkey (encryption-only key); corrupt key material that imports but cannot sign; very large message; kbpgp internal error.","commonSituations":"Encryption-only key used to sign; subkey capabilities not understood; key exported without its signing subkey.","solutions":["Use a private key that has a signing subkey / signing capability.","Re-export and validate the key material.","Reduce the message size and retry."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!/-----BEGIN PGP PRIVATE KEY BLOCK-----/.test(privateKey)) {\n    throw new Error('Signer argument is not an armoured PGP private key.');\n}","typeGuard":"const isArmouredPrivateKey = (s) =>\n    typeof s === 'string' && /-----BEGIN PGP PRIVATE KEY BLOCK-----/.test(s);","tryCatchPattern":"try {\n    signed = await chef.PGPSign(msg, [priv, pass]);\n} catch (e) {\n    if (/Couldn't sign/.test(e.message)) { /* inspect suffix for kbpgp cause */ }\n    else throw e;\n}","preventionTips":["Use a private key with a signing subkey / signing capability.","Validate the key material before signing.","Keep message size reasonable."],"tags":["pgp","kbpgp","signing","cryptography"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}