NodeJS使用验证密钥时openpgp.decrypt解密失败求助
OpenPGP解密Azure Function排查建议
问题描述
我有一个运行Node.js OpenPGP解密模块的Azure Function,解密自身生成的加密文件正常,但解密第三方用我的公钥加密的文件时,能成功获取对方密钥却解密失败,且无明确错误提示。
日志输出的message结构
message Bh { packets: Ku(2) [ ju { version: 3, publicKeyID: [Ke], publicKeyAlgorithm: 1, sessionKey: null, sessionKeyAlgorithm: null, encrypted: [Object], packets: Ku(0) [], fromStream: false }, Ou { version: 1, encrypted: [v], packets: Ku(0) [], fromStream: 'array' }, stream: v(2) [ [ju], [Ou], [Symbol(doneWritingResolve)]: [Function (anonymous)], [Symbol(doneWritingReject)]: [Function (anonymous)], [Symbol(doneWritingPromise)]: [Promise], [Symbol(readingIndex)]: 2 ] ], fromStream: false }
解密错误栈跟踪
Decryption error at /home/site/wwwroot/node_modules/openpgp/dist/node/openpgp.min.js:2:178460 at process.processTicksAndRejections (node:internal/process/task_queues:95:5) at async ju.decrypt (/home/site/wwwroot/node_modules/openpgp/dist/node/openpgp.min.js:2:291018) at async /home/site/wwwroot/node_modules/openpgp/dist/node/openpgp.min.js:2:345501 at async Promise.all (index 0) at async /home/site/wwwroot/node_modules/openpgp/dist/node/openpgp.min.js:2:344837 at async Promise.all (index 0) at async /home/site/wwwroot/node_modules/openpgp/dist/node/openpgp.min.js:2:344447 at async Promise.all (index 0) at async Bh.decryptSessionKeys (/home/site/wwwroot/node_modules/openpgp/dist/node/openpgp.min.js:2:344404)
函数代码
const openpgp = require('openpgp'); const { getPrivateKey, readMessage, isBinary, getDecryptFileName, getVerificationKey } = require('./utils'); const { BlobServiceClient } = require("@azure/storage-blob"); const { Buffer } = require('node:buffer'); const handler = async function (context, decryptThis) { context.log("JavaScript blob trigger function processed blob \nBlob:", context.bindingData.blobTrigger, "\nBlob Size:", decryptThis.length, "Bytes"); const blobName = context.bindingData.blobTrigger; try { context.log('getPrivateKey'); const decryptedKey = await getPrivateKey(blobName); context.log('getVerficationKey'); const verificationKey = await getVerificationKey(blobName, context.log); context.log('isBinary'); const fileIsBinary = isBinary(blobName); context.log('readMessage'); const message = await readMessage(decryptThis, fileIsBinary, context.log); context.log('message', message); const decryptOpts = { message, decryptionKeys: decryptedKey, format: fileIsBinary ? 'binary' : 'utf8', }; if (verificationKey) { context.log('has verificationKey'); decryptOpts.verificationKeys = verificationKey; decryptOpts.expectSigned = false; // Don't fail if signature fails verification. } context.log('decrypting...'); const decrypted = await openpgp.decrypt(decryptOpts); context.log('decrypted', decrypted); const data = decrypted.data; context.log('isBuffer', Buffer.isBuffer(data)); context.log(data ? 'has data ' + typeof data : 'no data'); const buf = Buffer.from(data); const saveName = getDecryptFileName(blobName); context.log(`desired filename ${saveName}`); const blobServiceClient = BlobServiceClient.fromConnectionString( process.env.FILESECURE_CONNECTION_STRING, ); const container = blobServiceClient.getContainerClient('decrypted'); const blob = container.getBlockBlobClient(saveName); const result = await blob.uploadData(buf); context.log(result); } catch (err) { context.log(`DECRYPT ERROR: ${err.message}`); } }; module.exports = handler;
排查建议
- 核对密钥匹配:确认第三方使用的公钥与你用于解密的私钥严格配对,通过message中的
publicKeyID字段核对两者的Key ID是否一致。 - 开启详细日志:在代码开头添加
openpgp.config.logger = console;,或者将Azure Function的日志级别设为Debug,获取解密过程的详细日志,重点关注sessionKey解密阶段的细节。 - 检查文件格式处理:确认第三方生成的PGP文件是ASCII-armored还是二进制格式,验证
readMessage工具函数是否能正确解析这两种格式。 - 确认私钥状态:添加日志输出
decryptedKey.isDecrypted(),确保获取到的私钥是完全解密(无密码保护或已正确解锁)的状态。 - 排除签名干扰:暂时移除
verificationKeys和expectSigned配置,仅执行纯解密操作,排查是否是签名验证环节的隐性错误导致解密失败。 - 检查版本兼容性:确认你的openpgp库版本与第三方加密工具版本是否兼容,从message中可以看到对方使用的是v3版本密钥,需确认当前库对v3密钥的支持是否有特殊要求。
- 本地测试验证:将第三方加密文件下载到本地,使用相同的私钥和openpgp库版本进行本地解密测试,排除Azure Function环境(如内存限制、编码处理差异)的影响。
内容的提问来源于stack exchange,提问作者Harvey A. Ramer
相关产品推荐
相关产品推荐

