Skip to content
HexaTransfer
Back to blog
Technical Deep Dives

How End-to-End Encryption Works for File Transfer

Understand how end-to-end encryption protects your files during transfer. A technical deep dive into cryptographic protocols and implementation.

End-to-end encryption for file transfer means the bytes leaving your device are encrypted with a key that never touches the server, and only your intended recipient can decrypt them. The server stores ciphertext, sees nothing meaningful, and could be breached without exposing your file's contents. The cryptographic recipe almost always involves a symmetric cipher like AES-256-GCM or XChaCha20-Poly1305 for the file itself, wrapped with a key exchange like X25519 ECDH or RSA-OAEP 2048/4096 for the key material. Here's exactly how that works in practice.

The Threat Model E2EE Actually Defends Against

E2EE specifically defends against: the transfer provider being hacked, subpoenaed, or malicious; network attackers intercepting TLS-decrypted traffic at proxies; backup snapshots of the storage bucket falling into the wrong hands; and insider access by employees of the service. It does not defend against malware on the sender's or recipient's device, phishing that captures the decryption link, or compromised recipient accounts. Understanding the model matters, because "encrypted" is often misused to mean "TLS-in-transit plus AES-at-rest on the server," which leaves the provider holding the keys.

Symmetric Encryption for the File Payload

Files are encrypted with a symmetric algorithm because public-key crypto is too slow for bulk data. The modern choice is AES-256-GCM, defined in NIST SP 800-38D, providing both confidentiality and authenticated integrity in one pass. A random 256-bit key and a unique 96-bit nonce (never reused with the same key) protect each file. XChaCha20-Poly1305, defined in RFC 8439 and RFC 8103, is an alternative that's often faster on devices without AES-NI hardware acceleration, like older ARM processors. Both produce a ciphertext plus a 128-bit authentication tag that detects any tampering.

Key Derivation From Passwords

When E2EE uses a password, the password itself is never the encryption key. That would be too weak against brute force. Instead, a key derivation function like PBKDF2-HMAC-SHA256 with 600,000 or more iterations (OWASP 2025 guidance), Argon2id with m=19 MiB and t=2 (RFC 9106), or scrypt (RFC 7914) stretches the password into a strong key. A random 128-bit or 256-bit salt prevents rainbow table attacks. The resulting key encrypts the file. The salt and the iteration count are stored with the ciphertext so the recipient can reconstruct the key when they enter the password.

Public-Key Wrapping for Account-Based Transfers

When recipients have accounts with published public keys, password entry isn't needed. The sender generates a random file encryption key (FEK), encrypts the file with AES-256-GCM using the FEK, then encrypts the FEK to each recipient's public key using X25519 ECDH key agreement per RFC 7748 combined with HKDF-SHA256 per RFC 5869 to derive a wrapping key, or RSA-OAEP per PKCS#1 v2.2 with SHA-256. The wrapped FEK sits next to the ciphertext. Only the holder of the recipient's private key can unwrap the FEK and decrypt the file. This is the Signal and WhatsApp model for messages, adapted for file payloads.

Link-Based E2EE Using URL Fragments

A clever trick in browser-based transfer is storing the decryption key in the URL fragment (the part after #). Fragments are never sent to the server in an HTTP request. A link like https://example.com/d/abc123#k=B9kZtR... carries the file ID server-side and the key client-side. The browser downloads the ciphertext, reads the fragment in JavaScript, and decrypts locally. The service never sees the key. Tools like Firefox Send (now discontinued), Send via ownCloud, and similar services use this pattern. The caveat is that if the link leaks anywhere, logs, screenshots, messaging app previews, the key leaks with it.

Integrity With AEAD and Hashes

Authenticated Encryption with Associated Data (AEAD) modes like GCM and ChaCha20-Poly1305 prevent tampering. A single bit flip in the ciphertext causes the authentication tag to fail validation, and the decryption function returns an error instead of garbage plaintext. On top of AEAD, many implementations compute a SHA-256 or BLAKE3 hash of the plaintext as a manifest entry so the recipient can verify after decryption that the file matches what the sender intended. This matters for large files transferred in chunks, where a partial delivery might otherwise succeed in parts and fail silently on a missing tail.

Chunked Encryption for Large Files

Encrypting a 10 GB file in one AES-GCM operation requires keeping 10 GB of state, which is impractical in browsers. Real implementations split the file into chunks, typically 1 MB to 16 MB each, and encrypt each chunk independently with a derived subkey and a counter-based nonce. The age encryption tool, defined at age-encryption.org, uses 64 KB chunks with ChaCha20-Poly1305. The Magic Wormhole protocol uses a streaming construction. Chunk boundaries also let browsers stream decryption via the Streams API, starting the download to disk before the whole file arrives, and support resumable uploads when network interruptions happen.

Transport Security on Top of E2EE

TLS 1.3 defined in RFC 8446 still matters on top of E2EE, not for confidentiality of the payload (the payload is already encrypted) but for privacy of metadata, file names, sizes, and timing. TLS 1.3 with forward-secret key exchange like X25519 means that even if the server's long-term key is compromised later, recorded sessions can't be decrypted. Certificate pinning or HSTS preload prevents downgrade attacks. Together, E2EE plus TLS 1.3 protects both the file contents and the operational pattern of who's sending what to whom.

Common Implementation Pitfalls

Three mistakes recur. First, reusing nonces with the same key in AES-GCM catastrophically breaks confidentiality; always use a fresh random nonce or a counter that never repeats. Second, implementing crypto with homemade routines instead of audited libraries like libsodium, Web Crypto API (SubtleCrypto), or BoringSSL; constant-time operations matter to prevent timing attacks. Third, not authenticating file metadata along with contents; if the sender's identity, filename, or recipient list isn't in the AAD (Associated Authenticated Data), an attacker can swap metadata undetected. Services like HexaTransfer address these by using standard Web Crypto primitives client-side with reviewed patterns.

Verifying a Service Actually Does E2EE

Read the marketing claims skeptically. True E2EE means the provider cannot decrypt files even if compelled by a court order. Look for published technical documentation describing the exact algorithms (AES-256-GCM, X25519, HKDF, PBKDF2 iteration counts), open-source client code that can be audited, and a threat model that acknowledges what E2EE does and doesn't defend against. Services that offer server-side password recovery on encrypted files are not doing true E2EE, they hold the keys. Services that claim "zero-knowledge" should back it up with a cryptographic protocol description, not just a slogan.

Try it at hexatransfer.com — free, no account, 10 GB max.

Send large files securely with end-to-end encryption

Transfer files up to 10 GB for free with end-to-end encryption. No account required. Your files are encrypted in your browser before upload — no one else can read them.

Send a file