尚未偵測到更新。GitHub 發布版本後會顯示在這裡。
Encrypted media storage & streaming.
翻譯準備中
正在載入完整 README。
檢視完整 README ↗data/
darkreel.db # rows of ciphertext
f47ac10b-58cc/
a3d9c8e2-7b14/
000000.enc [4.00 MB] # could be anything
000001.enc [2.00 MB] # padded to bucket size
000002.enc [1.00 MB] # random fill hides real size
thumb.enc [256 KB] # encrypted thumbnail
Every media file and directory in the data directory has its modification/access time set to 2024-01-01T00:00:00Z (directory mtimes are reset after each upload and deletion; darkreel.db itself is not). The inode change time (ctime) and, on filesystems that record one, the birth time cannot be set from userspace, so they still show roughly when each item was uploaded — see Disk encryption for why an encrypted volume is recommended. Every chunk is padded to 1, 2, 4, 8 or 16 MB (then whole MB), every thumbnail to 256 KB. Upload dates are coarsened to year only (delegation records use date granularity — see below). An attacker with root on your server sees uniform blobs with no meaningful metadata beyond chunk counts, bucket sizes and those inode times.
| Data | Visible to server? |
|---|---|
| File content | no - AES-256-GCM, per-file key |
| File names, types, MIME | no - encrypted metadata blob |
| File sizes, dimensions, duration | no exact values (encrypted metadata); approximate size only, from chunk count × bucket size |
| Thumbnails | no - separate encrypted key |
| Folder structure | no - encrypted blob |
| Passwords | not stored - Argon2id hash only. Sent to the server at login, registration, password change and recovery, where the KDF runs (see note) |
| Master key / private key | not stored in usable form - wrapped at rest. Held in plaintext only for the duration of a login, password-change or recovery request, then cleared (see note) |
| Usernames, public keys | yes |
| File count per user | yes (database row count) |
| Storage used per user | yes - sum of padded on-disk sizes, which the disk shows anyway |
| Upload timestamps | year only (coarsened) |
| Connected apps | yes - the name and URL the app supplied; authorize / last-used dates at day granularity (see "Timestamps are coarsened") |
What "zero-knowledge" means here — and where it stops. Everything above describes what the server holds at rest: a stolen
darkreel.db, a disk image, or a backup yields only Argon2id hashes and ciphertext, with no way to derive a key. That property is real and is the threat model Darkreel is built for.It is not the same as the server never seeing the material. Web Crypto has no Argon2id, so the browser cannot run the KDF; the password is sent over TLS and the server performs the derivation (see "Concurrent logins" under Known limitations). During a login the server necessarily holds your password and, briefly, your decrypted master key — it is cleared as soon as it has been re-wrapped for the client. Registration and admin-created accounts likewise generate the master key and X25519 keypair server-side. A password change or recovery goes further: the server unwraps the old private key, opens every item's sealed keys to re-seal them, and generates the new keys, all within that one request.
So: a passive operator, a database thief, or anyone with the disk after the fact learns nothing. An operator running modified server code can capture the password of anyone who logs in (and the keys of anyone who changes their password), and — because the server also serves the web app — can ship JavaScript that exfiltrates keys from the browser. If that is in your threat model, the mitigation is to run the binary you built from source yourself — which is the intended deployment anyway.
以上為 README 的開頭部分。其餘內容請閱讀原文。 檢視完整 README ↗