使用Openpgp.js加密消息报message参数类型错误如何解决
问题根因
你使用的openpgp@5.5.0版本对加密API做了破坏性更新,当前代码用的是v4版本的旧参数规范,同时存在公钥字符串带多余引号的问题,直接导致加密失败:
- 报错
Parameter [message] needs to be of type Message的直接原因:v5版本废弃了旧版直接传data字段传明文的写法,要求传入的message参数必须是通过官方方法生成的Message类型实例,不能直接传字符串。 - 公钥参数不兼容:v5版本废弃了旧版直接传
publicKeyArmored字符串的写法,要求传入提前解析完成的公钥对象,对应参数名改为encryptionKeys。 - 公钥字符串格式错误:从控制台输出可以看到,你传入的公钥首尾多了一层包裹的双引号,会导致公钥解析失败。
- 异步写法不规范:原代码没有等待encrypt异步执行完成,外层拿不到加密结果,容易出现时序问题。
修复后的可运行代码
<!-- 原有依赖引入不需要修改 --> <script src="https://unpkg.com/openpgp@5.5.0/dist/openpgp.min.js"></script>
async function EncryptMessage(pubkey, msg) { const openpgp = window.openpgp; // 清理公钥首尾多余的引号、空白字符 const publicKeyArmored = pubkey.value.trim().replace(/^"|"$/g, ''); const plainContent = msg.value; const emailData = { subject: "Message", body: plainContent }; // 解析公钥为openpgp可识别的密钥对象 const encryptionKey = await openpgp.readKey({ armoredKey: publicKeyArmored }); // 将待加密明文转为Message实例 const encryptMessage = await openpgp.createMessage({ text: JSON.stringify(emailData) }); // 执行加密 const encryptedResult = await openpgp.encrypt({ message: encryptMessage, encryptionKeys: encryptionKey, armored: true // 输出ASCII格式密文,默认即为true可省略 }); console.log('加密完成,密文如下:', encryptedResult); return encryptedResult; } // 测试调用 EncryptMessage( { value: "-----BEGIN PGP PUBLIC KEY BLOCK-----\n\nxjMEYsTz2BYJKwYBBAHaRw8BAQdAP6YvOhz9VKvV78ELW34Ufn1M10lDrv0k\n5A0zP0VHw8HNJjJTdGVwc0Zyb21IZWxsIDxhYmNkZWZnaEBhYmNkZWZnaC5j\nb20+wowEEBYKAB0FAmLE89gECwkHCAMVCAoEFgACAQIZAQIbAwIeAQAhCRAT\nF2pNLLmmchYhBGIZLWiMyuztkw8ilxMXak0suaZyVMUBAILAEJzIYtgA5pq6\nZorp8Zb6fP+ImwkD5g991SQmPhG0APoCbs+lcvrdavNLeYLRUh0VP4/iIp3U\nKtsoor1oCIYTDM44BGLE89gSCisGAQQBl1UBBQEBB0AqIqBiInlN3OUzZSoe\nYYY65gVLho588CULO/y30dWaOwMBCAfCeAQYFggACQUCYsTz2AIbDAAhCRAT\nF2pNLLmmchYhBGIZLWiMyuztkw8ilxMXak0suaZytisA/ilwmNQXcxs0zURR\nmuU/l3ngpfLcOE3G2D7g9JGaU+AtAQCqzJ11g0x6xbY7mJS+UdJjk6gb60mq\nqYlNhcVH5aw1CQ==\n=G/+7\n-----END PGP PUBLIC KEY BLOCK-----\n" }, { value: "hello world" } );
适配注意事项
- openpgp v5版本所有密钥相关参数不再支持直接传入armored格式字符串,必须先通过
readKey/readKeys/readPrivateKey方法解析为密钥对象后再传入,加密、解密、签名、验签的参数名统一调整为encryptionKeys/decryptionKeys/signingKeys/verificationKeys。 - 所有加解密、签名相关操作的内容参数,必须先通过
createMessage转为Message实例,不支持直接传入原始字符串、二进制数据。 - v5版本encrypt方法执行成功后直接返回armored格式密文(armored参数为true时),不需要再取返回值的
.data字段。 - 所有openpgp的API都是异步方法,必须使用
await或者.then()获取结果,避免出现时序问题。
内容的提问来源于stack exchange,提问作者2StepsFromHell
相关产品推荐
相关产品推荐

