如何排查OpenPGP.js消息解密时Session key解密失败问题?
问题描述
我用OpenPGP.js生成了名为customerPublicKey的公钥并加密消息,加密代码如下:
const { customerPublicKey} = await openpgp.generateKey({ type: 'rsa', passphrase: contract.passphrase, userIDs: [{ name: 'My Name', email: 'name@example.com' }] }); const message = await openpgp.createMessage({text: 'stringKey'}); const encrypted = await openpgp.encrypt({ message, // input as Message object encryptionKeys: customerPublicKey });
尝试用以下代码解密时抛出错误:
const buyerEncryptedKey = await openpgp.readMessage({ armoredMessage: encrypted }) const { privateKey } = await openpgp.generateKey({ type: 'rsa', passphrase: passphrase.value, userIDs: [{ name: 'My Name', email: 'name@example.com' }] }); const decryptionKeys = await openpgp.decryptKey({ privateKey: await openpgp.readPrivateKey({armoredKey:privateKey}), passphrase: passphrase.value })
错误信息:
error: Error: Error decrypting message: Session key decryption failed.
请问该如何调试此问题?有没有相关解决思路?
调试与解决思路
- 核心问题:解密时重新生成了全新的密钥对,和加密用的
customerPublicKey完全不匹配。OpenPGP加密的消息只能用对应公钥的私钥解密,新私钥无法解开用其他公钥加密的内容,这是导致错误的根本原因。 - 修复步骤:
- 加密阶段必须保留私钥:调用
openpgp.generateKey时,返回的对象包含customerPublicKey和privateKey两个部分,必须把这个privateKey存储到安全位置(比如本地存储、后端数据库),解密时必须使用这个私钥,不能重新生成。 - 修正解密流程:
// 加密时保存完整密钥对 const { customerPublicKey, privateKey: customerPrivateKey } = await openpgp.generateKey({ type: 'rsa', passphrase: contract.passphrase, userIDs: [{ name: 'My Name', email: 'name@example.com' }] }); // 将customerPrivateKey存入安全存储 // 解密流程 const encryptedMessage = await openpgp.readMessage({ armoredMessage: encrypted }); // 取出存储的customerPrivateKey const privateKeyObj = await openpgp.readPrivateKey({ armoredKey: customerPrivateKey }); // 解密私钥(需用生成时的密码) const decryptedPrivateKey = await openpgp.decryptKey({ privateKey: privateKeyObj, passphrase: contract.passphrase }); // 执行解密操作 const { data: decryptedText } = await openpgp.decrypt({ message: encryptedMessage, decryptionKeys: decryptedPrivateKey });
- 加密阶段必须保留私钥:调用
- 调试检查点:
- 密钥一致性验证:用
openpgp.readPublicKey读取加密用的customerPublicKey,再用openpgp.readPrivateKey读取解密用的私钥,调用私钥的getPublicKey()方法对比,确认是同一对密钥。 - 密码匹配检查:解密私钥的密码必须和生成密钥时的密码完全一致,注意大小写、特殊字符的差异。
- 消息完整性确认:加密后的
encrypted字符串在传输或存储过程中不能被截断、修改,确保解密时传入的是完整的加密内容。
- 密钥一致性验证:用
内容的提问来源于stack exchange,提问作者Boris K
相关产品推荐
相关产品推荐

