← Back to Projects
SecurityPCIJavaScriptC#.NETOpenPGP

PCI-Compliant Client File Encryption Portal

A browser-based drag-and-drop file encryption tool and companion .NET CLI app that lets non-technical clients encrypt files with a company PGP key entirely client-side — data never touches the server.

The Problem

A client needed to receive sensitive files from their own customers — people with zero technical background who had never heard of PGP, encryption, or secure file transfer. The compliance requirement was clear: files had to be encrypted before transmission. The business reality was equally clear: the client base could not be expected to install software, manage keys, or follow a multi-step technical process.

The existing workflow was a shared folder with a password. It wasn't PCI-compliant. It needed to be replaced immediately.

Warning

Giving non-technical users a PGP key and a how-to guide doesn't work. They'll email the file unencrypted anyway. The UX has to make the secure path the only path.

The Solution

Two components, built to work independently or together.

Web Portal (JavaScript, Single Page)

A self-contained single-page web application with one interaction: drag a file onto the page, get an encrypted file back. No login. No upload. No server round-trip.

The company's public PGP key is embedded directly in the page. The encryption runs entirely in the browser using the OpenPGP.js library — the file never leaves the client's machine unencrypted.

// Encrypt file client-side using embedded public key
const publicKey = await openpgp.readKey({ armoredKey: EMBEDDED_PUBLIC_KEY });
const encrypted = await openpgp.encrypt({
  message: await openpgp.createMessage({ binary: fileBytes }),
  encryptionKeys: publicKey,
});
// Write .pgp file to disk via browser download API
downloadBlob(encrypted, `${file.name}.pgp`);

The portal also displays the key's expiration date prominently. When the key is near expiry, clients are prompted to return to the portal to download the latest version — creating a forced key rotation path without any support intervention.

Desktop App (C# / .NET 10)

Not every client uses a browser workflow. For automated or enterprise-level senders, a self-contained .NET 10 executable handles the same encryption with a GUI and full CLI support for scripting and workflow injection.

# CLI usage — injectable into any pipeline
GreyHelixEncrypt.exe --input ./sensitive-report.xlsx --output ./encrypted/

The app is fully self-contained — no runtime install required. The same embedded public key approach is used, and expiration warnings surface in the GUI and as CLI exit codes so automated workflows can fail gracefully when the key needs rotation.

💡 Tip

Embedding the key in both the portal and the executable means key rotation forces a new artifact. Clients can't keep using old software with an expired key — compliance is structural, not procedural.

Key Design Decisions

Client-side only. The server never sees unencrypted data. This isn't just a compliance checkbox — it fundamentally eliminates a class of breach risk. If the server is compromised, there's nothing to steal.

Embedded public key. Eliminates key discovery errors. Clients cannot accidentally use the wrong key, an old key, or someone else's key.

Expiration as a forcing function. PCI requires periodic key rotation. By surfacing expiration prominently and requiring updated software to continue encrypting, rotation becomes automatic and auditable.

OWASP alignment. The portal was reviewed against OWASP Top 10. Since there's no server-side processing, the attack surface is minimal — but Content Security Policy headers, subresource integrity on the OpenPGP.js library, and no external network calls were enforced.

Build Time

This project was built in approximately 2 hours using Claude Code as a development assistant — from problem statement to working, tested, deployable artifacts.

Outcome

Note

Files sent through the portal are encrypted with a 4096-bit RSA public key before leaving the browser. Zero unencrypted data ever touches company infrastructure. Passed PCI DSS assessment.

The client deployed the portal publicly and distributes the desktop executable for enterprise senders. Key rotation is managed on a defined schedule — when the key expires, a new executable and updated portal are published. Clients who try to use the old version are told to upgrade. Compliance is self-enforcing.