{"record":{"id":"23ef4617fb092550","repo":"gchq/CyberChef","slug":"couldn-t-decrypt-message-with-provided-private-key","errorCode":null,"errorMessage":"Couldn't decrypt message with provided private key: ${err}","messagePattern":"Couldn't decrypt message with provided private key: (.+?)","errorType":"exception","errorClass":"OperationError","httpStatus":null,"severity":"error","filePath":"src/core/operations/PGPDecrypt.mjs","lineNumber":79,"sourceCode":"    async run(input, args) {\n        const encryptedMessage = input,\n            [privateKey, passphrase] = args,\n            keyring = new kbpgp.keyring.KeyRing();\n        let plaintextMessage;\n\n        if (!privateKey) throw new OperationError(\"Enter the private key of the recipient.\");\n\n        const key = await importPrivateKey(privateKey, passphrase);\n        keyring.add_key_manager(key);\n\n        try {\n            plaintextMessage = await promisify(kbpgp.unbox)({\n                armored: encryptedMessage,\n                keyfetch: keyring,\n                asp: ASP\n            });\n        } catch (err) {\n            throw new OperationError(`Couldn't decrypt message with provided private key: ${err}`);\n        }\n\n        return plaintextMessage.toString();\n    }\n\n}\n\nexport default PGPDecrypt;\n","sourceCodeStart":61,"sourceCodeEnd":88,"githubUrl":"https://github.com/gchq/CyberChef/blob/4290ea753912378913b1f3f54e0fc5720afeda5d/src/core/operations/PGPDecrypt.mjs#L61-L88","documentation":"Catch-all around kbpgp.unbox in PGPDecrypt.run. The private key imported fine (importPrivateKey succeeded and unlocked), but unboxing the armoured message failed - wrong key for this message, corrupt/truncated ciphertext, a message not encrypted for this key, or an incompatible OpenPGP packet structure. The underlying kbpgp error is appended after the colon.","triggerScenarios":"Private key does not correspond to the message recipient (no matching key packet); message uses an algorithm/feature kbpgp cannot handle; armoured message is malformed or truncated; passphrase was wrong yet produced a key that silently fails to match session keys.","commonSituations":"Using a public key to encrypt but the actual private key differs/has rotated; passphrase typo; cross-tool messages (GnuPG v2 SEIPD/AEAD features) kbpgp does not parse; message truncated in transit.","solutions":["Confirm the private key is the exact counterpart of the public key the message was encrypted for.","Re-enter the passphrase and verify the key unlocks correctly.","Re-export or re-armour the message to rule out truncation.","Decrypt locally with GnuPG to confirm the message + key pair is valid before blaming CyberChef/kbpgp."],"exampleFix":null,"handlingStrategy":"try-catch","validationCode":"if (!/-----BEGIN PGP MESSAGE-----/.test(encryptedMessage)) {\n    throw new Error('Input is not an armoured PGP message.');\n}\nif (!/-----BEGIN PGP PRIVATE KEY BLOCK-----/.test(privateKey)) {\n    throw new Error('Argument is not an armoured PGP private key.');\n}","typeGuard":null,"tryCatchPattern":"try {\n    plaintext = await chef.PGPDecrypt(message, [privKey, pass]);\n} catch (e) {\n    if (e instanceof OperationError && /Couldn't decrypt/.test(e.message)) {\n        // key/message mismatch - surface e.message to the user\n    } else throw e;\n}","preventionTips":["Verify key-to-message correspondence by decrypting locally with GnuPG first.","Ensure the passphrase is correct.","Keep the full armoured message intact (no truncation)."],"tags":["pgp","kbpgp","decryption","cryptography"],"backgroundTag":null,"analyzedSha":"4290ea753912378913b1f3f54e0fc5720afeda5d","analyzedAt":"2026-08-13T06:05:50.210Z","schemaVersion":2},"datasetVersion":"2026-08-13T09:17:06.757Z"}