End-to-end encrypted files are encrypted on the client before upload. The server never sees the plaintext data or the encryption key. E2E files use AES-256-GCM with PBKDF2 key derivation (100,000 iterations).
The flow is: derive a key from a passphrase using PBKDF2 with a random salt, encrypt the file with AES-256-GCM using a random IV, then upload the ciphertext along with the salt and IV as form parameters.
UPLOAD WITH E2E ENCRYPTION
import os
import base64
import requests
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
# Configuration
PASSPHRASE = "my-secret-passphrase"
FILE_PATH = "secret-document.pdf"
DOMAIN = "https://dev.one.gy"
# Generate random salt and IV
salt = os.urandom(16)
iv = os.urandom(12)
# Derive key from passphrase using PBKDF2
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
)
key = kdf.derive(PASSPHRASE.encode("utf-8"))
# Encrypt file with AES-256-GCM
with open(FILE_PATH, "rb") as f:
plaintext = f.read()
aesgcm = AESGCM(key)
ciphertext = aesgcm.encrypt(iv, plaintext, None)
# Upload encrypted data with salt and IV
response = requests.post(
f"{DOMAIN}/upload",
files={"file": ("secret-document.pdf", ciphertext)},
data={
"e2e": "true",
"e2e_salt": base64.b64encode(salt).decode(),
"e2e_iv": base64.b64encode(iv).decode(),
},
verify=False,
)
result = response.json()
print(f"Download: {result['download_url']}")
print(f"Manage: {DOMAIN}{result['redirect']}")
DOWNLOAD AND DECRYPT E2E FILE
GET
/f/{file_id}/encrypted
Download raw encrypted data for E2E files. The response includes X-E2E-Salt and X-E2E-IV headers containing the Base64-encoded salt and IV needed for decryption.
import base64
import requests
from cryptography.hazmat.primitives.ciphers.aead import AESGCM
from cryptography.hazmat.primitives.kdf.pbkdf2 import PBKDF2HMAC
from cryptography.hazmat.primitives import hashes
# Configuration
PASSPHRASE = "my-secret-passphrase"
FILE_ID = "your-file-uuid-here"
DOMAIN = "https://dev.one.gy"
OUTPUT_FILE = "decrypted-document.pdf"
# Download encrypted data
response = requests.get(
f"{DOMAIN}/f/{FILE_ID}/encrypted",
verify=False,
)
# Extract salt and IV from response headers (comma-separated decimal byte values)
salt = bytes([int(x) for x in response.headers["X-E2E-Salt"].split(",")])
iv = bytes([int(x) for x in response.headers["X-E2E-IV"].split(",")])
ciphertext = response.content
# Derive the same key from the passphrase
kdf = PBKDF2HMAC(
algorithm=hashes.SHA256(),
length=32,
salt=salt,
iterations=100000,
)
key = kdf.derive(PASSPHRASE.encode("utf-8"))
# Decrypt with AES-256-GCM
aesgcm = AESGCM(key)
plaintext = aesgcm.decrypt(iv, ciphertext, None)
with open(OUTPUT_FILE, "wb") as f:
f.write(plaintext)
print(f"Decrypted file saved to {OUTPUT_FILE}")
E2E PARAMETERS
e2e
string
"true" to mark upload as end-to-end encrypted
e2e_salt
string
Comma-separated decimal byte values of 16-byte salt used for PBKDF2 key derivation (e.g. "142,55,201,44,..."). Base64-encoded strings are also accepted.
e2e_iv
string
Comma-separated decimal byte values of 12-byte IV used for AES-256-GCM encryption (e.g. "10,233,78,..."). Base64-encoded strings are also accepted.
RESPONSE HEADERS (ENCRYPTED DOWNLOAD)
X-E2E-Salt
string
Comma-separated decimal byte values of salt for PBKDF2 key derivation
X-E2E-IV
string
Comma-separated decimal byte values of IV for AES-256-GCM decryption