You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Node.js用OpenPGP私钥解密报错‘未找到解密密钥包’求助

Node.js openpgp库解密失败:No decryption key packets found 及GPG警告处理

问题场景

在Node.js中使用openpgp库解密OpenPGP加密消息时失败,报错:

Decryption failed completely. Error details:
Error decrypting message: No decryption key packets found

加密消息由密钥7851C0CAFDBF2903(RSA 2048)加密,持有对应未加密私钥,但GPG命令行手动解密可成功,同时出现以下警告:

gpg: encrypted with rsa2048 key, ID 7851C0CAFDBF2903, created 2024-10-22
gpg: used key is not marked for encryption use.
gpg: WARNING: cipher algorithm CAST5 not found in recipient preferences

使用的解密代码:

const fs = require('fs');
const openpgp = require('openpgp');

async function decryptFile(encryptedFilePath, privateKeyFilePath, passphrase, outputFilePath) {
    try {
        const encryptedData = fs.readFileSync(encryptedFilePath, 'utf8');
        const privateKeyArmored = fs.readFileSync(privateKeyFilePath, 'utf8');

        // Parse the private key
        const privateKey = await openpgp.readKey({ armoredKey: privateKeyArmored });
        console.log('Private key fingerprint:', privateKey.getFingerprint());

        // Decrypt the private key if necessary
        let decryptedPrivateKey = privateKey;
        if (privateKey.isEncrypted) {
            decryptedPrivateKey = await openpgp.decryptKey({
                privateKey,
                passphrase
            });
        }

        const message = await openpgp.readMessage({ armoredMessage: encryptedData });
        const { data: decryptedData } = await openpgp.decrypt({
            message,
            decryptionKeys: decryptedPrivateKey,
            format: 'utf8'
        });

        // Ensure output directory exists
        const outputDir = outputFilePath.substring(0, outputFilePath.lastIndexOf('/'));
        if (!fs.existsSync(outputDir)) {
            fs.mkdirSync(outputDir, { recursive: true });
        }

        fs.writeFileSync(outputFilePath, decryptedData, 'utf8');
        console.log('Decryption successful! File saved to:', outputFilePath);
    } catch (error) {
        console.error('Decryption failed:', error.message);
        throw error;
    }
}

async function main() {
    const encryptedFilePath = './Testd/Trade_21112024.asc';
    const privateKeyFilePath = './key/private.key';
    const passphrase = '';
    const outputFilePath = './output/Trade_21112024.csv';

    try {
        await decryptFile(encryptedFilePath, privateKeyFilePath, passphrase, outputFilePath);
    } catch (error) {
        console.error('Program failed:', error.message);
    }
}

main();

核心问题:

  • 持有对应私钥,但openpgp库报错No decryption key packets found
  • GPG手动解密成功,但提示密钥未标记加密用途、CAST5算法不在收件人偏好中

已尝试操作:

  • 确认私钥正确且未加密
  • 尝试使用主私钥和子密钥解密
  • GPG手动解密成功,但Node.js脚本无法复现

问题解答

1. 为什么Node.js报错而GPG手动解密成功?

GPG对密钥用途的校验更宽松——即使密钥未标记加密用途,仍会尝试用其解密;但openpgp库默认严格检查密钥的用途标记,若密钥没有encrypt权限,会直接判定为无效解密密钥,触发No decryption key packets found错误。

另外,CAST5算法支持差异:GPG默认内置CAST5支持,而openpgp库可能默认未启用该算法,或在密钥偏好未声明时拒绝处理。

2. 如何解决密钥标记及CAST5算法警告?

修复密钥用途标记

通过GPG给密钥添加加密权限:

  1. 导入私钥到GPG:gpg --import private.key
  2. 进入密钥编辑界面:gpg --edit-key 7851C0CAFDBF2903
  3. 交互命令输入addkey,选择RSA加密类型,设置有效期后输入save保存
  4. 导出修改后的私钥:gpg --armor --export-secret-key 7851C0CAFDBF2903 > updated_private.key
    之后用修改后的私钥在Node.js中重试解密。

处理CAST5算法问题

在代码中显式启用CAST5算法,可在解密前添加配置:

// 启用CAST5算法支持
openpgp.config.cipherAlgorithms.add(openpgp.enums.cipher.cast5);

或在解密选项中指定允许的算法:

const { data: decryptedData } = await openpgp.decrypt({
    message,
    decryptionKeys: decryptedPrivateKey,
    format: 'utf8',
    config: {
        cipherAlgorithms: new Set([openpgp.enums.cipher.cast5, openpgp.enums.cipher.aes256])
    }
});

3. 代码是否遗漏子密钥或特定算法处理?

当前代码仅读取顶层私钥,若密钥包含子密钥,需确保子密钥被正确加载并具备解密权限。可修改代码如下:

// 读取私钥(确保加载所有子密钥)
const privateKey = await openpgp.readPrivateKey({ armoredKey: privateKeyArmored });

// 收集所有可用的解密密钥(主密钥+子密钥)
const allDecryptionKeys = [decryptedPrivateKey];
if (decryptedPrivateKey.subkeys.length > 0) {
    allDecryptionKeys.push(...decryptedPrivateKey.subkeys.map(subkey => subkey.privateKey));
}

// 解密时传入所有密钥
const { data: decryptedData } = await openpgp.decrypt({
    message,
    decryptionKeys: allDecryptionKeys,
    format: 'utf8'
});

同时建议升级openpgp库到最新版本,旧版本可能存在密钥解析或算法支持的bug:

npm update openpgp

内容的提问来源于stack exchange,提问作者CR00N0S

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.16 02:57:14