Client-Side Encrypted · PDF Sharing

Client-side encrypted PDF sharing, explained properly.

"End-to-end encrypted" gets used loosely. Here's the actual cryptographic mechanism behind a client-side encrypted PDF link — AES-256-GCM, key handling, fragment vs passphrase modes, and what the server literally cannot do. Note: "zero-knowledge" on this page refers to the server holding no information that could decrypt your file, not to formal zero-knowledge proofs (ZKPs) — the product does not use ZKPs.

lockAES-256-GCM vpn_keyPBKDF2-SHA256 · 310,000 linkFragment or passphrase memoryWeb Crypto API

What "zero-knowledge" means here

Quick disambiguation before anything else: this system does not use zero-knowledge proofs (ZKPs). The phrase "zero-knowledge" on this page refers to the weaker but practically useful property that the server storing your shared file has no knowledge — cryptographic or operational — that could be used to decrypt it. The key never touches the server, so the server cannot reveal it under any circumstance. Mechanism is plain client-side encryption plus a key that travels only in the URL fragment (or is derived from a passphrase the server never sees).

memory
Encryption happens in your browser
Not on the server, not in a worker you don't control — in your tab, via window.crypto.subtle. Verifiable in DevTools.
cloud_off
Only ciphertext is uploaded
The upload body is AES-256-GCM ciphertext. The PDF, filename, and metadata never reach the server in readable form.
vpn_key
The key rides with the recipient
Either in the URL fragment (never sent to servers) or derived from a passphrase the sender picks. Either way, we never see it.
block
No recovery = no backdoor
Lost the link or forgot the passphrase? The file is gone for good. Because the key never reaches our server, the recovery path that would weaken the guarantee doesn't exist.

How a client-side encrypted PDF link is built

A walkthrough of what the sender's browser, the server, and the recipient's browser each do — with the actual Web Crypto calls.

1 — Sender's browser
// 256-bit AES key, generated locally key = crypto.subtle.generateKey({name:"AES-GCM", length:256}) // fresh 96-bit IV per file iv = crypto.getRandomValues(new Uint8Array(12)) // encrypt locally; GCM gives us an auth tag for integrity ct = crypto.subtle.encrypt({name:"AES-GCM", iv}, key, pdfBytes) // upload ciphertext + iv (and salt, if passphrase mode) id = await PUT("/api/transfer", ct, {iv, expiry})
2 — Share link shape
// fragment mode: key lives after # link_f = `https://pdfpro.tools/s/${id}#${b64url(rawKey)}` // passphrase mode: no key in the link; recipient must know the passphrase link_p = `https://pdfpro.tools/s/${id}`
3 — Server stores opaque bytes
ciphertext = ??? // random-looking, unreadable iv = 12-byte nonce salt = 16-byte random (passphrase mode only) expiry = 24h free / 30d Pro
4 — Recipient's browser
// browsers never transmit the URL fragment to the server rawKey = /* from location.hash OR */ PBKDF2(passphrase, salt, 310_000, "SHA-256") ct = await GET("/api/transfer/" + id) pdf = crypto.subtle.decrypt({name:"AES-GCM", iv}, importKey(rawKey), ct) // browser serves pdf to Downloads

Fragment mode vs passphrase mode

Two ways to carry the key to the recipient. Same ciphertext guarantee, different usability / leakage trade-offs.

Fragment Mode

Key rides in the URL hash (#)

The simplest flow: copy the link, paste it into a chat to the recipient, done. The part of the URL after # is never sent to any web server by any compliant browser — that's what keeps the key private.

  • One step for the recipient — click the link.
  • Low friction, suitable for low-to-medium-sensitivity sharing.
  • Risk: if the link leaks in a screenshot or browser sync, the file leaks with it.
  • Use when you trust the channel (signed messenger, internal chat).
Passphrase Mode

Key derived from a passphrase (PBKDF2)

The sender picks a passphrase. The browser derives a 256-bit key via PBKDF2-SHA256 with 310,000 iterations over a random 128-bit salt. The salt is stored server-side; the passphrase is shared out-of-band (phone, Signal, in-person).

  • Two-factor share: the link and the passphrase travel separately.
  • Link alone is not enough — the ciphertext stays unreadable.
  • Passphrase strength matters: 310k iterations slow brute force but don't rescue a 6-character passphrase.
  • Use when the link might be forwarded or stored somewhere you don't fully trust.
PropertyFragment modePassphrase mode
Key carrierURL hash (#)Passphrase + salt
Server ever sees the keyNoNo
Server storesCiphertext + IVCiphertext + IV + salt
Recipient frictionClick linkClick link + type passphrase
Leakable via screenshotYes (link = key)No (link alone useless)
Brute-force resistant256-bit randomDepends on passphrase
Best forLow-friction sharing over trusted channelsHigher-sensitivity sharing

Why a server-stored ciphertext still protects you

People often ask: "if it's on your server, how is it private?" The answer is that ciphertext is not the file. Without the key, it's just random-looking bytes. Here's what that means in practice.

storage
Database breach = ciphertext leak
If an attacker compromised our database, they would leave with opaque bytes. Recovering a single file would require brute-forcing a 256-bit key — not feasible with known physics.
gavel
Subpoena produces ciphertext
A court can compel us to hand over what we have. What we have is ciphertext. A court order cannot retroactively create a key we never stored.
group
Insider access is neutralized
A rogue employee with full database credentials still cannot read files. The guarantee is enforced by math, not by access control.
timer
Expiry compounds the guarantee
Ciphertext is deleted on expiry (24 h free, up to 30 d Pro). After that, even the ciphertext is gone — the only copy of the file exists where it was decrypted to.

warningHonest limitations

Client-side encryption does not solve endpoint security. Malware on the sender's or recipient's device can steal the key from memory. A compromised browser extension can read the decrypted file. And a forwarded link in a group chat undoes every cryptographic guarantee. The architecture raises the cost of a breach; it does not eliminate all risk.

Client-side encryption vs other "secure" options

A clear comparison of common choices for sharing a PDF. Most options labeled "secure" are transport-encrypted — they protect the data in flight, but the receiving server still holds the plaintext and the key.

OptionTLS in transitServer can read fileExpiryRecipient account
Email attachmentUsually yesYes — at every hopForeverNot required
Generic cloud share linkYesYesOptionalSometimes
Password-protected PDFYesYes (if host has the file)NeverNot required
PDF Pro (fragment mode)YesNo24h / 30dNot required
PDF Pro (passphrase mode)YesNo24h / 30dNot required

Frequently asked questions

What does client-side encrypted PDF sharing actually mean?
It means the server storing your shared file literally cannot decrypt it. The encryption key is generated in the sender's browser, never uploaded, and only the recipient's browser can reconstruct it — either from the URL fragment or from a passphrase the sender shares out-of-band. The guarantee is enforced by cryptography, not by an access-control policy we could change. Note: this is distinct from formal zero-knowledge proofs (ZKPs), which this product does not use.
What encryption does PDF Pro use for client-side encrypted sharing?
AES-256-GCM symmetric encryption with a 96-bit random initialization vector per file. For passphrase mode, keys are derived via PBKDF2-SHA256 with 310,000 iterations over a 128-bit random salt. All crypto runs in the browser's native Web Crypto API.
What is the difference between fragment mode and passphrase mode?
Fragment mode puts the 256-bit key in the URL hash (after #), which browsers never send to any server. Anyone with the full link can decrypt. Passphrase mode derives the key from a passphrase the sender picks; the ciphertext stays unreadable without it. Passphrase mode is safer if the link leaks; fragment mode is easier for low-friction sharing. See the comparison table above.
Is a URL fragment really safe as an encryption key carrier?
Compliant browsers never transmit the fragment portion of a URL (the part after #) to the server. It stays client-side and is only visible to JavaScript running in the recipient's tab. That's what makes the share link itself the decryption credential — the key rides with the recipient, not with the upload. You can verify this in your browser's Network tab: the request URL is truncated at the ? or #.
Can PDF Pro or a court read files stored via client-side encrypted sharing?
No. The server stores AES-256-GCM ciphertext plus an initialization vector (plus a salt in passphrase mode). Without the key — which we never received — that data is cryptographically indistinguishable from random bytes. We can only disclose ciphertext, which is what we have.
What happens if I lose the link or forget the passphrase?
The file is permanently unrecoverable. This is by design — client-side encryption means no recovery path, because a recovery path would require us to hold the key. Save the passphrase in a password manager and store the link somewhere durable.
Is client-side encrypted PDF sharing free?
Yes. The free tier supports AES-256-GCM encryption and 24-hour link expiry with no signup required. The free-tier file cap is approximately 25 MB per transfer; Pro extends the expiry window to 30 days and raises file-size limits.
Does the recipient need an account?
No. The recipient clicks the link, their browser decrypts locally via the Web Crypto API, and they download the file — no signup, no install, no portal wall between them and the file.

Send one end-to-end encrypted link. Let it expire on schedule.

AES-256-GCM encryption in your browser. No signup, no server-side plaintext, no recovery backdoor.

sendCreate an Encrypted Link