Security Architecture

How PDF Pro's privacy claims actually work.

Everything on this page is verifiable in your browser's DevTools. The core rule: we should not be able to access your files — even if we wanted to. Below is how that rule is enforced at the crypto, storage, and request layer.

memoryClient-side WebAssembly & JS lockAES-256-GCM verifiedECDSA P-256 cloud_offClient-side encrypted storage

Four architectural pillars

Four technical choices define the security posture. They're enforced by the code that runs in your browser — not by a policy document.

memory
1. Local-first processing
PDF viewing, annotation, form filling, compression, merging, conversion, and signing run entirely in your browser via WebAssembly and JavaScript. For these tools, no file data ever leaves your device — verifiable in your Network tab.
key
2. Keys generated client-side
When you need to share a file, the encryption key is generated by the Web Crypto API inside your tab. It lives in memory, in the URL fragment, or (in passphrase mode) is derived on the recipient's device via PBKDF2. The server never sees it.
cloud_off
3. Client-side encrypted storage
Only AES-256-GCM ciphertext plus an initialization vector (and, for passphrase mode, a PBKDF2 salt) is stored. Without the key, this data is cryptographically indistinguishable from random bytes. Root database access would not help us decrypt it.
policy
4. Honest AI boundary
AI tools (chat, summary, translation) need readable text to work. We extract text client-side and send only that to the model provider — never the PDF file itself, never images, never embedded attachments. See the AI section below for full detail.

Encryption flow (Secure Transfer)

A byte-by-byte walkthrough of what happens when you drop a PDF into Secure Transfer and share the resulting link. Every step below runs in the browser except the storage of ciphertext.

Sender — in-browser
// 1. generate a fresh 256-bit key key = crypto.subtle.generateKey({name:"AES-GCM", length:256}) // 2. random 96-bit IV per file iv = crypto.getRandomValues(new Uint8Array(12)) // 3. encrypt the PDF bytes locally ct = crypto.subtle.encrypt({name:"AES-GCM", iv}, key, pdfBytes) // 4. upload ciphertext + iv — nothing else id = await fetch("/api/transfer", {method:"PUT", body: ct, headers:{"x-iv": hex(iv)}}) // 5. build the share link with the key in the URL fragment (#) link = `https://pdfpro.tools/s/${id}#${b64(rawKey)}`
Server — stores only ciphertext
ciphertext = opaque bytes // cannot be decrypted without the key iv = 12-byte nonce expiry = 24 h (free) / 30 d (Pro) // the URL fragment (#...) is NEVER sent to the server by browsers
Recipient — in-browser
// 1. browser loads the page; the "#..." fragment stays client-side rawKey = location.hash.slice(1) // 2. fetch the ciphertext ct = await fetch("/api/transfer/" + id) // 3. decrypt locally using Web Crypto pdf = crypto.subtle.decrypt({name:"AES-GCM", iv}, importKey(rawKey), ct) // 4. file ends up in the recipient's Downloads folder

The security guarantee is load-bearing on step 5 (sender) and step 1 (recipient): the URL fragment after # is not transmitted to the server by any compliant browser. This is what makes the link itself the decryption credential.

Passphrase mode replaces step 1 (sender) with PBKDF2-SHA256(passphrase, salt, 310_000). The salt is stored server-side; the passphrase is shared with the recipient out-of-band.

Signing flow (ECDSA P-256)

PDF signing uses ECDSA over the NIST P-256 curve. The private key is generated in your browser; the document never leaves your device.

key
Private key generation
An ECDSA P-256 keypair is generated via crypto.subtle.generateKey in your browser. The private key is exported to a password-wrapped JSON Web Key (JWK) that you can store locally.
fingerprint
SHA-256 hash & sign
The PDF bytes are hashed with SHA-256 client-side. That hash is signed by the private key. The signature is embedded into the PDF in a CMS container (PAdES-B-B profile).
verified
Offline-verifiable
Anyone with the public key (distributed alongside the document or as a fingerprint) can verify the signature offline. No server round-trip is required.
gavel
What this is not
Our signatures are cryptographically verifiable but are not qualified electronic signatures (QES) under eIDAS. They are tamper-evident proofs of integrity, suitable for internal workflows, not for regulatory-grade legal binding.

AI features — where we're honest about the boundary

AI Chat, AI Summary, and Translate need readable text. Here's exactly what leaves your device, and what doesn't.

description
Text extracted in-browser
The PDF is parsed locally via pdf.js. Only the extracted text (or, for scanned PDFs, the OCR output) is held in memory — the original file stays on your device.
outbound
Only text to the provider
We send that text string to the AI provider (Anthropic / OpenAI). The PDF itself, embedded images, fonts, and form data are never uploaded to any AI model.
block
No training on your content
Our provider contracts disable training on customer content. Requests are stateless — each one is scoped to your session.
info
When this matters
If your document contains regulated content (PHI, classified, legal-privileged) where even text extraction is sensitive, skip AI features and use the local tools (view, annotate, sign, compress, convert) — those operate 100% in-browser.

Threat model — what we defend against, what we can't

Being clear about the threat model is more useful than marketing. Here's what the architecture actually stops, and where it stops.

shieldWhat the architecture defends against

  • PDF Pro staff reading your files on our servers (we never hold the key).
  • Database-level breach of the transfer store (attacker sees ciphertext, not files).
  • Court-ordered disclosure of file contents (we can hand over ciphertext — which is all we have).
  • Mail-server retention of sensitive attachments (nothing ever hits your mail server).
  • Tampering with a signed PDF (ECDSA signature verification detects any byte change).

warningWhat no browser-based tool can defend against

  • A compromised endpoint (malware on your device) — keys live in memory on a device that must be trustworthy.
  • Someone shoulder-surfing the URL fragment — treat the share link like the file itself.
  • A weak passphrase in passphrase mode — PBKDF2 slows brute force but does not make a 6-character passphrase safe.
  • Recipient forwarding a decrypted file — transport security ends when the recipient saves the PDF.
  • Compromise of the browser itself or a malicious extension injecting into the page.

No "unhackable" claims. End-to-end encryption raises the cost of a breach significantly — it does not eliminate all risk, especially at the endpoint. For the most sensitive cases, combine Secure Transfer with a separate passphrase and a trusted-channel key exchange.

Frequently asked questions

Can PDF Pro decrypt my files?
No. Encryption keys are generated and held in the user's browser. For Secure Transfer, the server only stores AES-256-GCM ciphertext plus an initialization vector (plus a salt in passphrase mode). The key never reaches our infrastructure. Even with full database access, our operators cannot decrypt your file.
What exactly runs locally vs on the server?
Viewing, annotation, form filling, compression, merging, conversion, and signing all run 100% in your browser via WebAssembly and JavaScript — no file data ever leaves your device. AI features (chat, summary, translation) extract text locally and send only that text (never the PDF itself) to the model provider.
What algorithms does PDF Pro use?
AES-256-GCM for symmetric encryption (Secure Transfer), PBKDF2-SHA256 with 310,000 iterations for passphrase-derived keys, ECDSA over NIST P-256 for digital signatures, and SHA-256 for document hashing. All of these run via the browser's native Web Crypto API, which is audited, standardized, and not implemented by us.
Is this a legally binding electronic signature?
PDF Pro's signatures are cryptographically verifiable (ECDSA P-256 over a SHA-256 hash, PAdES-B-B profile) but are not qualified electronic signatures (QES) under eIDAS or equivalent regulations. For QES-grade legal binding, a certified trust service provider is required.
What happens if I forget a passphrase or lose a share link?
The file is permanently unrecoverable. That's the trade-off of end-to-end encryption — there is no recovery path, because we never had the key to begin with. Save the passphrase in a password manager and save the link somewhere durable.
Do you keep server-side logs of file activity?
We keep operational logs (request timing, error codes, IP addresses for rate limiting) but never plaintext file contents or encryption keys. Logs are retained on a short schedule — see our privacy policy for current retention windows.
Can a court order force you to reveal my files?
We can only hand over what we have: ciphertext. Without the decryption key — which stays on the sender's device or in the URL fragment the recipient holds — that ciphertext is not decryptable. A subpoena cannot retroactively recover a key we never stored.
Where can I verify the cryptographic claims myself?
Open your browser's DevTools → Network tab and watch what leaves the page during a Secure Transfer upload. You'll see ciphertext being PUT to the server, not the original PDF. The encryption code calls the Web Crypto API, which is built into your browser — not our code — and can be inspected by anyone.

Privacy as architecture, not marketing.

Try a Secure Transfer and inspect the Network tab yourself. No files are ever uploaded in plaintext.

lockTry Secure Transfer