gchq/CyberChef · error · OperationError
Couldn't decrypt message with provided private key: ${err}
Error message
Couldn't decrypt message with provided private key: ${err} What it means
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.
Source
Thrown at src/core/operations/PGPDecrypt.mjs:79
async run(input, args) {
const encryptedMessage = input,
[privateKey, passphrase] = args,
keyring = new kbpgp.keyring.KeyRing();
let plaintextMessage;
if (!privateKey) throw new OperationError("Enter the private key of the recipient.");
const key = await importPrivateKey(privateKey, passphrase);
keyring.add_key_manager(key);
try {
plaintextMessage = await promisify(kbpgp.unbox)({
armored: encryptedMessage,
keyfetch: keyring,
asp: ASP
});
} catch (err) {
throw new OperationError(`Couldn't decrypt message with provided private key: ${err}`);
}
return plaintextMessage.toString();
}
}
export default PGPDecrypt;
View on GitHub (pinned to 4290ea7539)
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.
Defensive patterns
Strategy: try-catch
Validate before calling
if (!/-----BEGIN PGP MESSAGE-----/.test(encryptedMessage)) {
throw new Error('Input is not an armoured PGP message.');
}
if (!/-----BEGIN PGP PRIVATE KEY BLOCK-----/.test(privateKey)) {
throw new Error('Argument is not an armoured PGP private key.');
} Try / catch
try {
plaintext = await chef.PGPDecrypt(message, [privKey, pass]);
} catch (e) {
if (e instanceof OperationError && /Couldn't decrypt/.test(e.message)) {
// key/message mismatch - surface e.message to the user
} else throw e;
} Prevention
- Verify key-to-message correspondence by decrypting locally with GnuPG first.
- Ensure the passphrase is correct.
- Keep the full armoured message intact (no truncation).
When it happens
Trigger: 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.
Common situations: 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.
Related errors
- Enter the private key of the recipient.
- Enter the public key of the signer.
- Could not identify a key manager.
- The data does not appear to be signed.
- Couldn't verify message: ${err}
AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13).
Data as JSON: /api/errors/23ef4617fb092550.
Report an issue: GitHub.