PGP File encryption and decryption

Iam7
3 min readAug 17, 2023

--

What is file encryption and why is it important?

It is a critical security measure to protect files with sensitive information with the help of cryptographic keys which will transform data into another form of representation which is commonly called ciphered data. By encrypting it’ll protect data from unauthorized access or alterations of data without a proper decryption algorithm and a key.

It is mostly used in personal life, government, healthcare, banking/finance, etc, wherever there is a requirement of protecting data from unauthorized access.

PGP Algorithm

Pretty Good Privacy is a data encryption and decryption program that provides cryptographic privacy and authentication for data communication. It’s often used for securing emails or other messages, but it can also be used to encrypt files, folders, and disks.

PGP uses a combination of both symmetric and asymmetric encryption. It starts by generating a pair of keys for asymmetric encryption:

  • Public Key: This key can be shared with anyone and is used to encrypt data.
  • Private Key: This key is kept secret by the owner and is used to decrypt data encrypted with the corresponding public key.

PGP file encryption using node.js

Step 1: Install the Openpgp package into your project (v5.x.x)

npm i openpgp

Step 2:

Snippet to generate the PGP private and public keys. We’ll be using these keys for encrypting and decrypting the files. In the real world, we’ll not be sharing private keys with the source who is encrypting the file. Only with the help of a private key and passphrase, the encrypted file can be decrypted.

const { privateKey, publicKey } = await openpgp.generateKey({
type: "rsa", // Type of the key
rsaBits: 4096, // RSA key size (defaults to 4096 bits)
userIDs: [{ name: "name", email: "name@example.com" }], // you can pass multiple user IDs
passphrase: "test", // protects the private key
});

Step 3:

Encrypt the file using the OpenPGP package, the encrypted file can be stored/transferred in any kind of network or storage securely. Where it can only be decrypted using the private key.

const fsp = require("fs/promises");
const openpgp = require("openpgp");

async function encryptFile() {
const publicKeyArmored = await fsp.readFile(
"./secure_keys/public.key",
"utf8"
);
const fileData = fs.createReadStream("file.pdf");
const publicKey = await openpgp.readKey({ armoredKey: publicKeyArmored });

const encrypted = await openpgp.encrypt({
message: await openpgp.createMessage({ binary: fileData }), // reading a binary of a filedata
encryptionKeys: publicKey,
format: "binary",
});

await fsp.writeFile("file.pdf.pgp", encrypted);
console.log("File encrypted successfully.");
}

Step 4:

Decrypting the encrypted file, post this you’ll have the original file.

async function decryptFile() {
const privateKeyArmored = await fsp.readFile(
"./secure_keys/private.key",
"utf8"
);
const encryptedData =await fsp.readFile("file.txt.pgp");

const privateKey = await openpgp.decryptKey({
privateKey: await openpgp.readPrivateKey({ armoredKey: privateKeyArmored }),
passphrase: "test",
});

const decrypted = await openpgp.decrypt({
message: await openpgp.readMessage({ binaryMessage: encryptedData }),
decryptionKeys: privateKey,
});

await fsp.writeFile("file-decrypted.txt", decrypted.data);
console.log("File decrypted successfully.");
}

the above code snippets give you the basic file encryption/decryption logic, in case of large files where the size is more than the available memory needs to be encrypted in chunks. Rest works fine with the above approach and minor tweaking is required for production usage.

If you found this post helpful, feel free to check out the complete code and resources on my GitHub repo. Don’t hesitate to leave comments, ask questions, or contribute to the project. Happy coding!

--

--