How Our End-to-End Encryption Works (And Why We Can't Read Your Files)

Security9 min readPublished 2026-09-06Updated 2026-09-17
Quick Answer / Key Takeaway

"End-to-end encrypted" gets printed on a lot of landing pages. This is the actual mechanism behind ours — which keys exist, where they are generated, what our server receives, and the one check only you can perform. Including the honest part: what we can still see, and what happens when a direct connection isn't possible.

What End-to-End Actually Means

Most file services encrypt in two places: between your browser and their server (that is just HTTPS), and on their disks (that is "encryption at rest"). Both are worth having. Neither stops the service itself from reading your file, because in both cases the service holds the keys.

End-to-end encryption means something stricter: the file is encrypted before it leaves the sending device, and can only be decrypted on the receiving device. Every machine in between — our servers included — handles bytes it cannot interpret.

The rest of this page is the specific mechanism, so you can judge the claim rather than take it on faith.

Step 1: The Key Exchange

When you open a receiving room, your browser generates a brand-new RSA-2048 key pair using the browser's built-in Web Crypto API. Two things matter about this:

  • The private key never leaves that browser tab. It is not sent to us, not stored on disk, and not attached to any account. Close the tab and it is gone for good.
  • The pair is generated fresh for every session. Yesterday's transfer used a different key. Even if someone recorded that traffic and later got hold of your device, there is no long-lived key sitting around to open it with.

The public half is shared — that is what public keys are for. It travels through our server to the sender, and it is useless for decryption. Public keys only lock; the matching private key unlocks.

The sender's browser then generates a random 256-bit AES key for the file data itself, encrypts that key with the receiver's public key, and sends the wrapped result across. The receiving browser unwraps it with its private key.

At the end of this exchange, exactly two devices know the AES key: the sender's and the receiver's. Our server relayed a public key and an encrypted blob it has no way to open.

Why two kinds of encryption? RSA is well suited to protecting something small like a key, but far too slow for gigabytes of file data. AES is fast enough to encrypt a large file in real time but needs both sides to already share a secret. Using RSA to deliver an AES key gets both properties at once — this pattern is standard, and it is the same one behind HTTPS.

Try an Encrypted Transfer

Open GetFileShare E2E on both devices and watch the safety code match before a single byte moves.

Step 2: Encrypting the File

The file is never encrypted as one piece. It is split into chunks, and each chunk is encrypted separately with AES-256-GCM before it is transmitted.

Three details do real work here:

  • A fresh random IV for every chunk. Reusing an initialization vector in GCM is catastrophic; generating a new random one each time means identical chunks never produce identical ciphertext.
  • The chunk's sequence number is authenticated. It is bound into the encryption as additional authenticated data, so a chunk cannot be silently reordered, duplicated, or moved between transfers. Tampering makes decryption fail rather than produce plausible-looking garbage.
  • GCM authenticates as well as encrypts. Every chunk carries an authentication tag. A single flipped bit makes that chunk fail to decrypt, so nothing can be modified in transit without detection.

When the last chunk lands, the receiving browser computes a SHA-256 hash of the reassembled file and checks it against the hash the sender computed before sending. Same file, or an error — no silent corruption.

The encryption runs on a background worker thread, so a large file does not freeze the page while it works.

Step 3: The Safety Code

This is the part most services leave out, and the reason we show you something extra on screen.

Everything above rests on one assumption: that the sender received the receiver's real public key. But the sender learns that key through our server. So picture a compromised server that substitutes its own public key instead. The sender wraps the AES key for the impostor. The server unwraps it, reads the file, re-wraps the same key for the real receiver, and passes it along. Both people see a completely normal transfer. The encryption worked flawlessly — for the wrong recipient.

No amount of AES or RSA fixes this, because nothing in the mathematics tells the sender whose key they were handed. It has to be checked outside the channel being attacked.

That is what the safety code is: 8 emoji and a short hex string, shown on both screens. Each side derives it from the key it is actually using — the receiver from its own public key, the sender from the key it was given. Compare them:

  • They match → the sender is encrypting to the receiver's genuine key. Nobody is in the middle.
  • They differ → stop. The key was substituted somewhere in between.

A server cannot fake a match. Producing a different key whose fingerprint collides with the real one would mean breaking SHA-256.

The comparison has to happen somewhere we do not control — glance at the other person's screen, or read the code aloud on a call. You are already sharing a room code with them, so it costs a couple of seconds.

This check is what turns "we cannot read your files" from a promise into something you can verify. Skip it and you are trusting us. Do it and you do not have to.

When Direct Connection Fails: The Relay Path

The fast path is a direct WebRTC connection between the two browsers. File data travels device to device and never touches our infrastructure at all.

That connection is not always used. Strict corporate firewalls, symmetric NAT, and most mobile carrier networks (CGNAT) block direct peer connections, and when that happens we relay the data through our server so the transfer still completes. Small transfers take the relay too, without attempting a peer connection at all: negotiating one takes longer than simply sending the file.

The encryption does not change. Chunks are encrypted in the sending browser before they are handed to the relay, exactly as on the direct path. What passes through our server is ciphertext, an initialization vector, and a sequence number. We do not hold the AES key: it was wrapped for the receiver's public key, and our server never had the matching private key.

So on the relay path the server is a bridge, not a reader. It moves opaque blocks between two sockets. If we wanted to read your file there, we could not — we would need the receiver's private key, which was generated inside their browser and never sent to us.

The same goes for our TURN server, which some connections use to route around firewalls. It forwards packets that are already encrypted twice over: your AES-GCM ciphertext, inside the connection's own encrypted transport.

What the relay path costs you is speed, not confidentiality. It is slower than a direct connection, and every byte travels through our bandwidth instead of straight across the room.

What We Can Still See

A security page that only lists strengths is not being straight with you. Here is what our servers do observe:

  • File sizes and types. These travel with the transfer request so the receiver can decide whether to accept, and they stay in the record we keep of the transfer. The file name travels with the request for the same reason, but is dropped before that record is written — it is the field most likely to describe what you sent. A cloud upload is different: there the name is stored, because serving the share needs it.
  • IP addresses and timing. Who connected, when, and for how long — ordinary connection metadata, and unavoidable for a service that has to route your traffic.
  • Room codes and session activity. How rooms were created and joined.
  • On the relay path, the encrypted byte stream. We can see that roughly N megabytes moved. We cannot see what they contain.

What we never have is the file contents, or the keys that would decrypt them. Not in memory, not on disk, not in a backup. On the direct path the file data does not reach us at all; on the relay path it passes through as ciphertext we cannot open.

Our Privacy Policy covers retention periods for the metadata above.

Frequently Asked Questions

If the file goes through your server on the fallback path, isn't that no longer end-to-end?

It is still end-to-end. The term describes where encryption and decryption happen — in the two browsers — not the physical route the bytes take. The relay carries ciphertext it has no key for. The difference between the direct and relay paths is speed and bandwidth, not who can read the file.

What happens if I skip the safety code check?

The transfer works normally and your file is still encrypted in transit. What you lose is the ability to detect a substituted key. Skipping it means trusting that our server handed over the correct public key; performing the check means you do not have to.

Can you recover a file I sent yesterday?

No. Nothing is stored. On the direct path the data never reaches us; on the relay path it passes through memory as ciphertext and is never written to disk. The session keys are destroyed when the browser tabs close.

Do I have to trust your JavaScript?

Yes — and that is true of every in-browser encryption tool, ours included. The code that encrypts your file is code we serve you, so verifying it means inspecting what your browser actually loaded. This is the honest limit of browser-based end-to-end encryption, and anyone who tells you otherwise is overselling.

Is a password-protected cloud upload the same thing?

No. Cloud uploads are a different product with different trade-offs — the file is stored on our infrastructure so the recipient can fetch it later. E2E transfer needs both people present at the same time and stores nothing.