I have an Azure Function running node's openpgp decryption module. It works fine when we decrypt our own files, but we are receiving a file from a third party that is signed with their public key. We are able to retrieve their key, but every time I try to decrypt the message, it fails without any error.
I am including the entire code of my function, but without the helper utilities. Each function called in the utility works properly and returns the keys and message as expected.
In case it helps, the returned message, when logged, looks like the following:
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
}
Below is the generic error with stack trace:
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)
Below is the function body:
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 \n Blob:", context.bindingData.blobTrigger, "\n Blob 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;
I have been uploading my encrypted file, and every time, it is able to access all my keys and read the message, but it fails on decryption. Since the error is so generic, I am left wondering what to try next. Do you have any advice?