|
1 | | -# FileShot Zero-Knowledge Encryption (ZKE) |
| 1 | +# FileShot Zero-Knowledge Encryption |
2 | 2 |
|
3 | | -Client-side, open-source zero-knowledge encryption used by FileShot.io. |
| 3 | +Client-side, open-source zero-knowledge encryption used by [FileShot.io](https://fileshot.io). |
4 | 4 |
|
5 | | -This repository contains the browser-based encryption system that powers FileShot’s zero-knowledge upload pipeline. All encryption occurs locally in the user’s browser via the Web Crypto API. FileShot servers never receive passwords, keys, or unencrypted data. |
| 5 | +All encryption happens in the browser via the Web Crypto API. The server receives only ciphertext — it never sees the key, the password, or the plaintext file. |
6 | 6 |
|
7 | | -This ensures files stored and shared through FileShot remain unreadable by FileShot, third parties, attackers, or governments. |
| 7 | + |
8 | 8 |
|
9 | 9 | --- |
10 | 10 |
|
11 | | -## What Zero-Knowledge Encryption Means |
| 11 | +## How the Zero-Knowledge Model Works |
12 | 12 |
|
13 | | -Zero-knowledge encryption ensures: |
| 13 | +FileShot uses two modes of zero-knowledge encryption, both implemented in this library: |
14 | 14 |
|
15 | | -* Files are encrypted before they leave the browser. |
16 | | -* Decryption keys never leave the user’s device. |
17 | | -* FileShot servers store only encrypted blobs. |
18 | | -* No one, including FileShot, can decrypt user files. |
| 15 | +### URL-Fragment Mode (production default) |
19 | 16 |
|
20 | | -All cryptographic operations are performed client-side using the Web Crypto API. |
| 17 | +1. A cryptographically random 256-bit key is generated in the browser. |
| 18 | +2. The file is encrypted with AES-256-GCM using that key. |
| 19 | +3. Only the ciphertext is uploaded to the server. |
| 20 | +4. The key is placed in the URL fragment (`#key=...`) of the share link. |
| 21 | +5. The URL fragment is **never transmitted to the server** — browsers do not include fragments in HTTP requests by design. |
| 22 | +6. The recipient decrypts entirely in-browser using the key from the URL. |
21 | 23 |
|
22 | | ---- |
23 | | - |
24 | | -## Full FileShot Feature Set |
25 | | - |
26 | | -### Core Privacy Features |
27 | | - |
28 | | -* Client-side zero-knowledge encryption. |
29 | | -* No accounts or identity required. |
30 | | -* No analytics, tracking, or fingerprinting. |
31 | | -* Keys and passwords never transmitted. |
32 | | -* Open-source encryption implementation. |
33 | | -* Servers store encrypted data only. |
34 | | - |
35 | | -### Upload & Sharing Features |
36 | | - |
37 | | -* Uploads up to 15GB per file. |
38 | | -* Secure, shareable links. |
39 | | -* Expiration settings from 1 hour to 30 days. |
40 | | -* Optional password protection. |
41 | | -* Anonymous download information. |
42 | | -* NVMe-backed high-speed infrastructure. |
43 | | - |
44 | | -### Monetization Features |
45 | | - |
46 | | -* Optional paid-access downloads. |
47 | | -* Up to 50% commission per download. |
48 | | -* Payments integrated without compromising encryption. |
49 | | - |
50 | | -### Built-In File Tools |
51 | | - |
52 | | -#### PDF Tools |
53 | | - |
54 | | -* Edit PDFs. |
55 | | -* Merge PDFs. |
56 | | -* Split PDFs. |
57 | | -* Compress PDFs. |
58 | | -* Convert PDFs to and from images. |
59 | | - |
60 | | -#### Conversion Tools |
61 | | - |
62 | | -* Video to MP4. |
63 | | -* Audio to MP3. |
64 | | -* Image format conversion (PNG, JPG, WebP, AVIF). |
65 | | -* Document conversion (PDF ↔ DOCX, TXT → PDF, etc.). |
66 | | -* Archive conversion (ZIP, TAR, 7Z when supported). |
67 | | - |
68 | | -#### Archive Tools |
| 24 | +The server is architecturally incapable of decrypting the file even under compulsion. |
69 | 25 |
|
70 | | -* Create ZIP, TAR, and 7Z archives. |
71 | | -* Extract ZIP, RAR, TAR, GZ, and 7Z. |
| 26 | +### Password Mode |
72 | 27 |
|
73 | | -#### Compression Tools |
| 28 | +Users may optionally set a password. The key is derived from the password via PBKDF2 (100,000 iterations, SHA-256). The password itself is never transmitted. The recipient enters the password in their browser to decrypt. |
74 | 29 |
|
75 | | -* Image compression. |
76 | | -* Video compression. |
77 | | -* General file compression. |
78 | | - |
79 | | -#### Utility Tools |
80 | | - |
81 | | -* File metadata inspection. |
82 | | -* SHA-256 hash generation. |
83 | | -* Secure local file deletion. |
| 30 | +--- |
84 | 31 |
|
85 | | -### Platform-Level Features |
| 32 | +## Security Details |
86 | 33 |
|
87 | | -* Zero-knowledge encryption pipeline. |
88 | | -* Secure link signing. |
89 | | -* Client-side metadata handling. |
90 | | -* Private, self-hosted infrastructure. |
91 | | -* Modern high-performance UI. |
92 | | -* Web Crypto API for all cryptographic operations. |
| 34 | +| Parameter | Value | |
| 35 | +|-----------|-------| |
| 36 | +| Cipher | AES-256-GCM | |
| 37 | +| Key derivation | PBKDF2, SHA-256, 100,000 iterations | |
| 38 | +| Salt | 16 bytes, random per-file | |
| 39 | +| IV | 12 bytes, random per-encryption | |
| 40 | +| Key size | 256 bits | |
| 41 | +| Crypto API | Web Crypto API (native browser, no dependencies) | |
93 | 42 |
|
94 | 43 | --- |
95 | 44 |
|
96 | 45 | ## Quick Start |
97 | 46 |
|
98 | 47 | ### Try the Demo |
99 | 48 |
|
100 | | -1. Open `demo.html`. |
101 | | -2. Select a file and encrypt it. |
102 | | -3. Download the encrypted output. |
103 | | -4. Decrypt using the same password. |
| 49 | +1. Open `demo.html` in any modern browser. |
| 50 | +2. Select a file and a password. |
| 51 | +3. Click Encrypt — you get an encrypted blob. |
| 52 | +4. Click Decrypt with the same password — you get the original file back. |
104 | 53 |
|
105 | | ---- |
| 54 | +No server involved. Works fully offline. |
106 | 55 |
|
107 | | -## Using in Your Own Project |
| 56 | +### Embed in Your Project |
108 | 57 |
|
109 | 58 | ```html |
110 | 59 | <script src="zero-knowledge.js"></script> |
111 | 60 | <script> |
112 | | - const fileInput = document.getElementById('fileInput'); |
113 | | - const file = fileInput.files[0]; |
114 | | - const password = 'your-secure-password'; |
115 | | -
|
116 | | - const result = await window.zeroKnowledgeEncrypt(file, password); |
117 | | -
|
118 | | - const decrypted = await window.zeroKnowledgeDecrypt( |
119 | | - encryptedBlob, |
120 | | - password, |
121 | | - originalFileName, |
122 | | - originalFileType |
123 | | - ); |
| 61 | +const file = document.getElementById('fileInput').files[0]; |
| 62 | +
|
| 63 | +// Encrypt |
| 64 | +const { encryptedBlob, metadata } = await window.zeroKnowledgeEncrypt(file, 'strong-password'); |
| 65 | +
|
| 66 | +// Decrypt |
| 67 | +const decryptedBlob = await window.zeroKnowledgeDecrypt( |
| 68 | + encryptedBlob, |
| 69 | + 'strong-password', |
| 70 | + metadata.originalName, |
| 71 | + metadata.originalType |
| 72 | +); |
124 | 73 | </script> |
125 | 74 | ``` |
126 | 75 |
|
127 | 76 | --- |
128 | 77 |
|
129 | | -## How It Works |
| 78 | +## API Reference |
| 79 | + |
| 80 | +### `zeroKnowledgeEncrypt(file, password)` |
| 81 | + |
| 82 | +Encrypts a `File` or `Blob` client-side. |
| 83 | + |
| 84 | +**Returns:** |
| 85 | +```js |
| 86 | +{ |
| 87 | + encryptedBlob: Blob, // AES-256-GCM ciphertext |
| 88 | + metadata: { |
| 89 | + originalName: string, // Original filename |
| 90 | + originalSize: number, // Original size in bytes |
| 91 | + originalType: string, // Original MIME type |
| 92 | + encryptedSize: number // Encrypted size in bytes |
| 93 | + } |
| 94 | +} |
| 95 | +``` |
| 96 | + |
| 97 | +### `zeroKnowledgeDecrypt(encryptedBlob, password, originalName, originalType)` |
130 | 98 |
|
131 | | -1. **Key Derivation** – A random salt is generated; a key is derived using PBKDF2 (100,000 iterations, SHA-256). |
132 | | -2. **Encryption** – AES-256-GCM encrypts the file with a 12-byte IV. |
133 | | -3. **Upload** – Only the encrypted blob is transmitted. |
134 | | -4. **Storage** – Servers store encrypted blobs and encrypted metadata only. |
135 | | -5. **Download & Decryption** – Recipients decrypt files entirely in-browser using the shared password. |
| 99 | +Decrypts an encrypted `Blob` client-side. |
| 100 | + |
| 101 | +**Returns:** A `Blob` containing the decrypted file, with the original filename and MIME type. |
136 | 102 |
|
137 | 103 | --- |
138 | 104 |
|
139 | | -## Security Details |
| 105 | +## Encryption Pipeline |
140 | 106 |
|
141 | | -* AES-256-GCM. |
142 | | -* PBKDF2 (SHA-256, 100,000 iterations). |
143 | | -* 16-byte salt. |
144 | | -* 12-byte IV for GCM. |
145 | | -* 256-bit keys. |
| 107 | +``` |
| 108 | +User selects file |
| 109 | + | |
| 110 | + v |
| 111 | +Generate random 16-byte salt |
| 112 | +Generate random 12-byte IV |
| 113 | + | |
| 114 | + v |
| 115 | +PBKDF2(password, salt) → 256-bit AES key |
| 116 | + | |
| 117 | + v |
| 118 | +AES-256-GCM encrypt(file bytes, key, IV) |
| 119 | + | |
| 120 | + v |
| 121 | +Output: [salt][IV][ciphertext][auth tag] |
| 122 | + | |
| 123 | + v |
| 124 | +Only ciphertext leaves the browser |
| 125 | +``` |
146 | 126 |
|
147 | 127 | --- |
148 | 128 |
|
149 | 129 | ## File Structure |
150 | 130 |
|
151 | 131 | ``` |
152 | 132 | fileshot-zke/ |
153 | | -├── zero-knowledge.js |
154 | | -├── demo.html |
| 133 | +├── zero-knowledge.js # Core encryption/decryption library |
| 134 | +├── demo.html # Standalone browser demo |
155 | 135 | ├── README.md |
156 | | -└── LICENSE |
| 136 | +└── LICENSE # MIT |
157 | 137 | ``` |
158 | 138 |
|
159 | 139 | --- |
160 | 140 |
|
161 | | -## Testing |
162 | | - |
163 | | -* Encrypt and decrypt files. |
164 | | -* Validate metadata. |
165 | | -* Verify incorrect passwords fail. |
| 141 | +## Browser Support |
166 | 142 |
|
167 | | ---- |
| 143 | +| Browser | Minimum Version | |
| 144 | +|---------|----------------| |
| 145 | +| Chrome | 37+ | |
| 146 | +| Firefox | 34+ | |
| 147 | +| Safari | 11+ | |
| 148 | +| Edge | 12+ | |
| 149 | +| Opera | 24+ | |
168 | 150 |
|
169 | | -## API Reference |
| 151 | +All modern browsers support the Web Crypto API. No polyfills needed. |
170 | 152 |
|
171 | | -### zeroKnowledgeEncrypt(file, password) |
172 | | - |
173 | | -Encrypts a file client-side. |
| 153 | +--- |
174 | 154 |
|
175 | | -Returns: |
| 155 | +## Key Security Properties |
176 | 156 |
|
177 | | -```js |
178 | | -{ |
179 | | - encryptedBlob: Blob, |
180 | | - metadata: { |
181 | | - originalName: string, |
182 | | - originalSize: number, |
183 | | - originalType: string, |
184 | | - encryptedSize: number |
185 | | - } |
186 | | -} |
187 | | -``` |
| 157 | +- **No server-side keys.** The server stores only ciphertext and encrypted metadata. |
| 158 | +- **No key transmission.** Keys travel only in URL fragments, which are stripped from HTTP requests. |
| 159 | +- **No dependencies.** The library uses only the native browser `crypto.subtle` API. |
| 160 | +- **Authenticated encryption.** AES-GCM includes a MAC — tampered ciphertext is rejected before decryption. |
| 161 | +- **Forward secrecy per file.** Each file gets a unique salt and IV. |
188 | 162 |
|
189 | | -### zeroKnowledgeDecrypt(encryptedBlob, password, originalName, originalType) |
| 163 | +--- |
190 | 164 |
|
191 | | -Decrypts encrypted data client-side. |
| 165 | +## Live Implementation |
192 | 166 |
|
193 | | -Returns: |
194 | | -A Blob containing the decrypted file. |
| 167 | +This library powers [FileShot.io](https://fileshot.io) — a zero-knowledge file sharing service. |
195 | 168 |
|
196 | | ---- |
| 169 | +**Plans:** |
197 | 170 |
|
198 | | -## Important Security Notes |
| 171 | +| Plan | File Size Limit | Storage | Price | |
| 172 | +|------|----------------|---------|-------| |
| 173 | +| Free | 50 GB per file | Unlimited | $0 | |
| 174 | +| Lite | 100 GB per file | Unlimited | $1/mo | |
| 175 | +| Pro | 250 GB per file | Unlimited | $4/mo | |
| 176 | +| Creator | Unlimited | Unlimited | $9/mo | |
199 | 177 |
|
200 | | -* Use strong, unique passwords. |
201 | | -* Share passwords securely. |
202 | | -* Lost passwords cannot be recovered. |
203 | | -* Keep browsers and systems up to date. |
204 | | -* Use HTTPS in production. |
| 178 | +You can audit the encryption running in production at: [https://fileshot.io/verify-encryption.html](https://fileshot.io/verify-encryption.html) |
205 | 179 |
|
206 | 180 | --- |
207 | 181 |
|
208 | | -## Verification |
| 182 | +## Desktop App |
209 | 183 |
|
210 | | -Users can verify: |
| 184 | +FileShot also has an open-source Electron desktop app: [github.com/FileShot/fileshot-desktop](https://github.com/FileShot/fileshot-desktop) |
211 | 185 |
|
212 | | -* Client code matches this repository. |
213 | | -* Encryption runs entirely in the browser. |
214 | | -* No keys or plaintext leave the client. |
215 | | - |
216 | | -Verification page: [https://fileshot.io/verify-encryption.html](https://fileshot.io/verify-encryption.html) |
| 186 | +Features tray integration, drag-and-drop uploads, background transfers, and a virtual FileShot Drive. |
217 | 187 |
|
218 | 188 | --- |
219 | 189 |
|
220 | | -## Browser Support |
| 190 | +## Security Policy |
221 | 191 |
|
222 | | -* Chrome 37+ |
223 | | -* Firefox 34+ |
224 | | -* Safari 11+ |
225 | | -* Edge 12+ |
226 | | -* Opera 24+ |
| 192 | +Report vulnerabilities privately: [fileshot.adm@gmail.com](mailto:fileshot.adm@gmail.com) |
227 | 193 |
|
228 | 194 | --- |
229 | 195 |
|
230 | | -## Security Policy |
231 | | - |
232 | | -Report vulnerabilities privately to: |
| 196 | +## Testing |
233 | 197 |
|
234 | | -[fileshot.adm@gmail.com](mailto:fileshot.adm@gmail.com) |
| 198 | +- Encrypt a file, verify the encrypted blob contains no plaintext. |
| 199 | +- Decrypt with the correct password — verify original bytes match exactly. |
| 200 | +- Decrypt with an incorrect password — verify an error is thrown (GCM authentication failure). |
| 201 | +- Verify the salt and IV are different on every encryption of the same file. |
235 | 202 |
|
236 | 203 | --- |
237 | 204 |
|
238 | 205 | ## License |
239 | 206 |
|
240 | | -MIT License. |
| 207 | +MIT — see [LICENSE](LICENSE). |
| 208 | + |
| 209 | +Copyright (c) 2025 FileShot.io |
0 commit comments