gchq/CyberChef · error · OperationError

Couldn't decrypt message with provided private key

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.

Solutions

  1. Confirm the private key is the exact counterpart of the public key the message was encrypted for.
  2. Re-enter the passphrase and verify the key unlocks correctly.
  3. Re-export or re-armour the message to rule out truncation.
  4. 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

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


AI-assisted analysis of gchq/CyberChef@4290ea7539 (2026-08-13). Data as JSON: /api/errors/23ef4617fb092550. Report an issue: GitHub.

Appendix: 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)