I would like to encrypt a zip file using OpenPGP.js (https://browserpgp.github.io/). All processing needs to be done on the client-side, without involvement of Node.js. Using the javascript-based browserpgp.js, encryption of plaintext file is easy, but encryption of zip files are challenging. I am attaching the code I use to encrypt the zip file. Since, the contents of zip file are not text, so I have used guides for working with binary data from https://github.com/openpgpjs/openpgpjs. I believe the resulting file after encryption of a zip file should be in raw/binary format, and the resulting file saved from the following encryption code is in binary. However, I verified it and its cannot be decrypted.
I am using the Kleopatra desktop OpenPGP tool (https://www.openpgp.org/software/kleopatra/) to verify if the resulting encrypted file. Using the tool, I tested to see if I can decrypt the encrypted file using my private key. The resulting binary file cannot be decrypted using the Kleopatra tool. So I was wondering what is wrong with this code, as the resulting file should be decryptable using Kleopatra.
You can create two public keys using the tool here: https://browserpgp.github.io
function openpgp_encryptZIPFile(){
var zip = new JSZip();
zip.file("Hello.txt", "Hello World\n");
var img = zip.folder("images");
zip.generateAsync({type:"blob"})
.then(function(content) {
console.log('contents: ' + content);
encryptedZipFile = OpenPGPEncryptDataZipFile(content);
});
}
async function OpenPGPEncryptDataZipFile(zipBlob)
{
//This is my public key
const key1 = `somekey1`; //you would have to put a public key here
//This is the testuser public key
const key2 = `somekey2`; //you would have to put another public key here
const publicKeysArmored = [key1, key2];
//create a combined key
const publicKeys = await Promise.all(publicKeysArmored.map(armoredKey => openpgp.readKey({ armoredKey })));
var binaryData = new Uint8Array(zipBlob);
//https://github.com/openpgpjs/openpgpjs/blob/main/README.md
//For OpenPGP.js v4 syntax is: const message = openpgp.Message.fromBinary(binaryData);
//For OpenPGP.js v5 syntax is: const message2 = await openpgp.createMessage({ binary: binaryData });
//`const {data: encrypted}' OR `const { message }' OR just `const encrypted'
const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ binary: binaryData }),
encryptionKeys: publicKeys,
//signingKeys: privateKey // optional
format: 'binary'
});
console.log('encrypted: ' + encrypted);
var encryptedBlob = new Blob([encrypted],{type: 'text/plain'});
//var encryptedBlob = new Blob([encrypted], {type: "octet/stream"});
saveAs(encryptedBlob, 'test.zip.enc' );
}