Guides
Private files
Encrypted on your device with AES-256-GCM. Portaldot stores ciphertext, and the key only ever lives in the share link.
How it works
- PotDrive generates a random 256-bit key and a 96-bit IV with
crypto.getRandomValues. - It builds a plaintext of a 4-byte header length, a JSON header with the real name and type, then the file.
- It encrypts with AES-256-GCM through WebCrypto. The 128-bit tag authenticates the whole envelope.
- The envelope is chunked and stored like any file. The registry records the name as empty and the type as
application/octet-stream. - The key is base64url-encoded into the link fragment:
/f/<cid>#k=<key>.
Envelope format
| Bytes | Field |
|---|---|
0–3 | Magic PDE1 |
4–15 | IV, 12 bytes |
16–… | AES-256-GCM ciphertext and 16-byte tag over: u32be(len) ‖ JSON{name, mime} ‖ data |
seal and open
import { sealFile, openFile } from "@potdrive/sdk";
const { bytes, key } = await sealFile(data, { name: "plan.pdf", mime: "application/pdf" });
const { data: plain, meta } = await openFile(bytes, key); // throws "Wrong key for this file"Why the fragment
Browsers never send the part of a URL after # to a server. Opening a private link loads the page, then the page fetches the ciphertext from Portaldot and decrypts it locally. The PotDrive server, the gateway and the RPC node never see the key or the plaintext.
What still leaks
- The ciphertext size, within the chunk size.
- That your account stored something, and when.
- Nothing else: name, type and content are inside the envelope.