Skip to main content

How it works

  1. 1 Encrypt

    Files are sealed in your browser with AES-256-GCM. The server never sees plaintext.

  2. 2 Upload

    Only ciphertext travels — chunked under the CDN limit, with a live progress bar.

  3. 3 Share

    Send the link. Send the password or private key on a separate channel.

  4. 4 Decrypt

    The recipient opens the link, unlocks locally, and downloads the original file.

Zero-knowledge · E2E encrypted

Encrypted File Share

Files are encrypted in your browser before upload. The server only stores ciphertext and never sees your password or keys.

Min 12 characters. Send the password on a separate channel — never in the share link.

Drop a file here or click to browse

Max 1 GB · Always encrypted in-browser · Chunked upload (CDN-safe) · Link never contains the secret

Your uploads 0

No encrypted uploads yet from this connection.

Decrypt a local EPCYFS file

Use this if you already have a .epcyfs file (downloaded elsewhere).

Privacy: send passwords and private keys out-of-band. Do not put secrets in the URL. Ciphertext is deleted after expiry (or after one download if enabled).

How it works

Zero-knowledge: encryption and decryption run entirely in your browser with WebCrypto (AES-256-GCM). The server rejects any upload that is not a valid EPCYFS container.

Password mode derives an AES key with PBKDF2-SHA256 (600,000 iterations) and a random salt. Certificate mode wraps a random AES key with RSA-OAEP-SHA256 (≥3072) or derives it via ECDH P-384 + HKDF-SHA-384.

Large files are encrypted in 1 MiB chunks and uploaded in 64 MiB pieces (under the CDN request limit). Filename and MIME are encrypted inside the container.

Share the decrypt link with the recipient, and send the password or private key through a different channel (Signal, in person, etc.). The link never contains the secret.

FAQ

Expert guide · File Share

What it does

Encrypted File Share accepts only client-side encrypted EPCYFS containers. Your browser encrypts the file with a password (PBKDF2-SHA256 600k → AES-256-GCM) or a recipient public key (RSA-OAEP ≥3072 or ECDH P-384 + HKDF, hybrid AES-256-GCM) before upload. The server stores ciphertext only, never plaintext, passwords or private keys. Recipients open the share link, download the ciphertext and decrypt locally with the same password or matching private key sent through a separate channel.

Why it matters

  • Zero-knowledge transfer: The VPS and any CDN logs only see opaque ciphertext and a random id — not filenames, MIME types or contents
  • Password or certificate: Choose a shared passphrase, or wrap the file key to a recipient's RSA/ECDH public key so only their private key can open it
  • Abuse resistance: Unencrypted uploads are rejected at the API; OpenSSL Salted__ and arbitrary blobs fail the EPCYFS magic check
  • Short retention: TTL of 1, 3 or 7 days plus optional one-time download limits how long ciphertext sits on disk
  • Separate channel for secrets: The share URL never embeds the password or private key — send those by Signal, in person, etc.

How to read the results

  • Share link (/tools/file-share/d/<id>): Opens the decrypt page; the raw ciphertext is at /api/tools/file-share/download/<id>
  • Mode badge (password / rsa / ecdh): Which key-wrap was used; the downloader must supply the matching secret
  • Expires after: Chosen TTL (24 h, 3 d or 7 d) from upload time; expired files are swept on the next list/upload
  • One-time: After the first ciphertext download the blob is deleted; a second GET returns 404/410
  • Local decrypt: On the tool page you can also pick a .epcyfs file obtained elsewhere and decrypt it offline in the browser

Technical background

EPCYFS v1 is a self-describing binary container: magic "EPCYFS", version 1, mode byte (1=password, 2=RSA-OAEP-SHA256, 3=ECDH-P-384+HKDF), a length-prefixed KDF/wrap section, then an AES-256-GCM encrypted metadata blob (original filename, MIME, size, chunk count) and 1 MiB plaintext chunks each with their own 96-bit IV, AAD carrying the chunk index and a final flag, and a 128-bit GCM tag. Password mode derives the file key with PBKDF2-SHA256 at 600 000 iterations and a random 16-byte salt. Public-key modes generate a random 256-bit AES key, encrypt the file with it, and wrap that key to the recipient's SPKI (RSA-OAEP with SHA-256, modulus ≥3072 bits, or ECDH P-384 whose shared secret is passed through HKDF-SHA-256).

All cryptography runs in the browser via WebCrypto. The SvelteKit API only accepts bodies whose first bytes match the EPCYFS header; anything else (plaintext, OpenSSL Salted__, random data) returns HTTP 400. Limits: 1 GB ciphertext (chunked upload), 15 GB total storage, 50 concurrent files, 20 uploads per IP per hour, selectable TTL 1/3/7 days, optional one-time download. Stored names are <48-hex-id>.epcyfs with a sibling .meta.json that intentionally omits the original filename. Downloads are served as application/octet-stream with Content-Disposition: attachment and X-Content-Type-Options: nosniff. Post-quantum hybrid (ML-KEM-768) is planned once a small self-hosted library is vetted; it is not available yet.

Common errors and how to fix them

Problem Upload fails with 'Only client-side encrypted EPCYFS files are accepted'
Fix Encrypt in the browser with the Password or Certificate tab before uploading. OpenSSL, gpg or zip AES archives are not EPCYFS and will be rejected.
Problem Upload fails with 'File exceeds 1 GB limit' (HTTP 413)
Fix Ciphertext must be ≤1 GB. Compress then encrypt, or split across multiple shares.
Problem Decryption failed (wrong password/key or tampered file)
Fix GCM authentication failed. Check the password/private key, and that the .epcyfs was not truncated or modified in transit.
Problem Second download of a one-time link returns 404/410
Fix Expected: the ciphertext was deleted after the first download. Re-upload if you still need to share it.
Problem HTTP 429 rate limit
Fix Max 20 uploads per IP per hour. Wait or use another network.

Do it from the command line

macOS

# Prefer the web UI (chunked upload, up to 1 GB). Encrypt in the browser; API is init/chunk/complete:
curl -F file=@secret.txt.epcyfs -F ttlMs=86400000 -F oneTime=0 \
  https://epcybertools.com/api/tools/file-share
# Download ciphertext only (decrypt in the browser or a local EPCYFS tool):
curl -OJ https://epcybertools.com/api/tools/file-share/download/<id>

Windows

# Upload EPCYFS ciphertext produced by the web UI:
curl.exe -F file=@secret.txt.epcyfs -F ttlMs=86400000 -F oneTime=0 https://epcybertools.com/api/tools/file-share
# Download ciphertext:
curl.exe -OJ https://epcybertools.com/api/tools/file-share/download/<id>

Linux

# Upload an already-encrypted EPCYFS container (created in the web UI):
curl -F file=@secret.txt.epcyfs -F ttlMs=86400000 -F oneTime=0 \
  https://epcybertools.com/api/tools/file-share
# Download ciphertext:
curl -OJ https://epcybertools.com/api/tools/file-share/download/<id>

More questions about File Share

Can the server read my file?

No. Encryption and decryption happen only in your browser. The server validates the EPCYFS header and stores opaque bytes.

What algorithms are used?

AES-256-GCM for content; PBKDF2-SHA256 (600k) for passwords; RSA-OAEP-SHA256 (≥3072) or ECDH P-384 + HKDF for public-key wrap.

Is post-quantum (ML-KEM) available?

Not yet. Hybrid ML-KEM-768 is planned once a small self-hosted library is vetted.

Limits?

1 GB per file (chunked), 15 GB total storage, 50 concurrent files, 20 uploads/IP/hour, TTL 1/3/7 days, optional one-time download.

Can I upload from the command line?

Only an already-encrypted .epcyfs produced by the web UI (or a compatible EPCYFS encoder). Plain files are rejected.