Security

PGP Encryption for Files in Node.js with openpgp.js

A practical encryption workflow for sensitive documents where files are encrypted before storage and decrypted only for authorized access.

If compliance matters, server-side access controls are not enough. You also want encrypted-at-rest content that remains unreadable if object storage is exposed.

1) Separate key roles early

Use one key pair per environment and rotate keys on a schedule. Keep private keys in managed secrets storage. Never keep long-term keys in repo or static env files.

2) Encrypt before upload

javascriptencrypt-file.js
1import * as openpgp from "openpgp";
2
3export async function encryptBuffer(buffer, armoredPublicKey) {
4 const publicKey = await openpgp.readKey({ armoredKey: armoredPublicKey });
5 const message = await openpgp.createMessage({ binary: buffer });
6
7 return openpgp.encrypt({
8 message,
9 encryptionKeys: publicKey,
10 format: "binary"
11 });
12}

3) Decrypt only inside authorized flow

javascriptdecrypt-file.js
1import * as openpgp from "openpgp";
2
3export async function decryptBuffer(encryptedBytes, armoredPrivateKey, passphrase) {
4 const privateKey = await openpgp.decryptKey({
5 privateKey: await openpgp.readPrivateKey({ armoredKey: armoredPrivateKey }),
6 passphrase
7 });
8
9 const message = await openpgp.readMessage({ binaryMessage: encryptedBytes });
10 const { data } = await openpgp.decrypt({
11 message,
12 decryptionKeys: privateKey,
13 format: "binary"
14 });
15
16 return data;
17}

4) Operational controls

  • Audit every decrypt event with user ID and reason.
  • Use short-lived signed URLs when sending decrypted files.
  • Rotate keys and re-encrypt batches during low-traffic windows.
  • Run routine restore tests so encrypted backups remain usable.
Encryption without key management discipline creates a false sense of security.

Encryption at rest works best as part of a wider security posture. Combine it with strong authentication using WebAuthn passkeys in a Node.js app, broader production hardening for a Node.js application, and, for regulated teams, our SOC 2 compliance checklist for SaaS startups.

5) Key lifecycle management and rotation policy

Encryption quality depends on key lifecycle discipline. Define generation, storage, rotation, revocation, and retirement policy before launching encryption features. Without this, the cryptography can be correct but the system still unsafe.

  • Rotate encryption keys on a fixed schedule and after incidents.
  • Segregate duties for key access versus application deployment.
  • Version encrypted objects so re-encryption jobs are traceable.
  • Maintain emergency recovery procedure with dual control.

6) Secure download flow for decrypted content

Never expose decrypted files to long-lived public URLs. Decrypt in a controlled service, apply authorization checks, and issue short-lived signed responses. Log who requested what, when, and why.

7) Compliance and audit design

  • Capture immutable audit events for encrypt and decrypt operations.
  • Retain logs based on policy and jurisdiction requirements.
  • Implement data retention and secure deletion routines.
  • Test restore and decrypt drills quarterly.

PGP encryption in Node.js FAQ

Q: Is file-level PGP encryption enough by itself? A: No. You still need strict access controls, monitoring, and key management controls.

Q: When should we decrypt files? A: Only at the moment of authorized use, and only in controlled backend processes.

Need help building this?

Let our team build it for you.

Dude Lemon builds production-grade web apps, APIs, and cloud infrastructure. Get a free consultation and project proposal within 48 hours.

Start a Project

Related articles

View all articles →