Skip to content

Commit e49d936

Browse files
axpnetEhudKirshclaude
committed
docs(security): add AeroCrypt overlay page, correct v3 status and crypto
New features/aerocrypt.md documents the native AeroCrypt overlay (AECR v3), kept clearly distinct from AeroVault (a Cryptomator-class container) and rclone crypt (the interop overlay), with the shared-crypto-core note. v3 is the shipped Archive vault tier, not Experimental/Beta (fixed in encryption.md, wrapper-stack.md, aerovault.md). The overlay is renamed AeroFTP-Crypt to AeroCrypt with the correct shipped crypto (AES-256-GCM-SIV content, AES-256-KW DEK wrap, AES-256-SIV filenames, Argon2id 128 MiB, key-bound config MAC), replacing the stale AES-256-GCM + HKDF. cli crypt cipher corrected to AES-256-GCM-SIV. Nav adds AeroCrypt Overlay under Features and Security. Co-authored-by: EhudKirsh <EhudKirsh@users.noreply.github.com> Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
1 parent 8a1eb10 commit e49d936

6 files changed

Lines changed: 106 additions & 18 deletions

File tree

.vitepress/config.ts

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -229,6 +229,7 @@ export default defineConfig({
229229
{ text: 'AeroFile', link: '/features/aerofile' },
230230
{ text: 'AeroSync', link: '/features/aerosync' },
231231
{ text: 'AeroVault', link: '/features/aerovault' },
232+
{ text: 'AeroCrypt Overlay', link: '/features/aerocrypt' },
232233
{ text: 'AeroAgent', link: '/features/aeroagent' },
233234
{ text: 'AeroPlayer', link: '/features/aeroplayer' },
234235
{ text: 'AeroTools', link: '/features/aerotools' },
@@ -319,6 +320,7 @@ export default defineConfig({
319320
{ text: 'Encryption', link: '/security/encryption' },
320321
{ text: 'Wrapper Stack', link: '/security/wrapper-stack' },
321322
{ text: 'Error Correction', link: '/security/error-correction' },
323+
{ text: 'AeroCrypt Overlay', link: '/features/aerocrypt' },
322324
{ text: 'rclone crypt', link: '/features/rclone-crypt' },
323325
{ text: 'Credentials', link: '/security/credentials' },
324326
{ text: 'Credential Isolation', link: '/credential-isolation' },

cli/commands.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -531,7 +531,7 @@ Jobs are persisted in SQLite (`~/.config/aeroftp/jobs.db`) and survive daemon re
531531

532532
### crypt
533533

534-
Zero-knowledge encrypted storage on any provider. Content encrypted with AES-256-GCM (64KB blocks, hardware accelerated), filenames encrypted with AES-256-SIV, key derivation via Argon2id.
534+
Zero-knowledge encrypted storage on any provider: the CLI surface of the [AeroCrypt overlay](/features/aerocrypt). Content encrypted with AES-256-GCM-SIV (64 KB blocks) under a per-file random key wrapped with AES-256-KW, filenames encrypted with AES-256-SIV, key derivation via Argon2id (128 MiB). New objects are written as the hardened v3 (`AECR`) format; legacy v1/v2 overlays stay readable.
535535

536536
```bash
537537
# Initialize encrypted overlay

features/aerocrypt.md

Lines changed: 85 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
# AeroCrypt Overlay
2+
3+
AeroCrypt is AeroFTP's **native client-side encryption overlay**. It turns any server, protocol or provider into a high-security, zero-knowledge store: the remote only ever holds ciphertext and obfuscated names, while the decrypted view is browsed exactly like a normal server in the standard dual panel.
4+
5+
AeroCrypt is an **overlay**, not a container. One local file maps to one remote object (a per-file encrypted blob with an encrypted name), so an encrypted scope stays listable, navigable and syncable object by object. This is the opposite shape from [AeroVault](/security/encryption), which seals many files into a single `.aerovault` container. The two coexist on purpose: AeroVault for a sealed, portable bundle, AeroCrypt for an ongoing encrypted mirror on a provider you do not trust at rest.
6+
7+
> **Community design attribution.** The AeroCrypt naming (AeroCrypt for the native overlay, Rclone Crypt for the interoperable one), the wrapper-and-overlay model it sits in, the opt-in "no default cipher" rule, and much of the format and UX were shaped by a sustained design contribution from **Ehud Kirsh** across the [Wrappers / Overlays roadmap (#272)](https://github.com/axpdev-lab/aeroftp/discussions/272) and the [AeroVault and cryptography design thread (#276)](https://github.com/axpdev-lab/aeroftp/discussions/276).
8+
9+
::: info AeroVault vs AeroCrypt: two different things
10+
**AeroVault is to Cryptomator what AeroCrypt is to rclone crypt.** AeroVault is a sealed encrypted **container** (a single `.aerovault` vault you open); AeroCrypt is a transparent per-file **overlay** that encrypts each remote object in place and is browsed like a normal server.
11+
12+
They **share the same audited crypto core** (one implementation, one audit pass, extracted from the AeroVault v3 engine in v4.0.5): AES-256-GCM-SIV content, AES-256-KW key wrapping, AES-256-SIV filenames, and the Argon2id (128 MiB, t=4, p=4) KDF.
13+
14+
They **do not share their shape**: AeroVault seals many files into one container with the full wrapper stack (small-file packing, content-defined chunking, deduplication, per-chunk zstd, and the v4 error-correction extension); AeroCrypt encrypts object by object with no container and no cross-file dedup. Different on-disk formats too: `AEROVAULT3` container plus manifest, versus the per-object `AECR` format plus a `.aeroftp-crypt.json` config.
15+
:::
16+
17+
There is **no default cipher**: you actively choose AeroCrypt (native) or [Rclone Crypt](/features/rclone-crypt) (the interop lane), by clicking in the GUI or typing in the CLI. Nobody encrypts by tapping Enter.
18+
19+
## What AeroCrypt gives you
20+
21+
- **Zero-knowledge on any backend.** AeroCrypt wraps the storage so the remote bucket only ever holds ciphertext and obfuscated names, on any of the supported backends, even the ones that offer no encryption of their own. On a provider that already encrypts at rest (Filen, MEGA, Internxt) it is a second independent layer keyed only by you, genuine double encryption where the key that matters never leaves your device.
22+
- **Browses like a normal server.** You unlock once, and from then on the decrypted folder reads, navigates, gets and puts exactly like a connected server in the dual panel, with clear names on your side and ciphertext on the provider's.
23+
- **AeroCrypt Profile (per-profile binding).** An overlay can be bound to a saved server profile so it auto-unlocks on connect, with a toggle in the connection form, per-session binding that survives a profile switch or reconnect, and edit-mode guards that lock the binding so it cannot be silently changed.
24+
25+
## The AECR format (v3)
26+
27+
AeroCrypt writes one encrypted object per file, with the format magic `AECR`. The current version is v3:
28+
29+
| Layer | Algorithm | Detail |
30+
| ----- | --------- | ------ |
31+
| Content encryption | AES-256-GCM-SIV (RFC 8452) | Per-file random data key (DEK), 64 KiB plaintext blocks, per-block random nonce |
32+
| DEK wrapping | AES-256-KW (RFC 3394) | The per-file DEK is wrapped under the master key |
33+
| Master key derivation | Argon2id (128 MiB, t=4, p=4) | Derives the master key from your password and the per-overlay salt |
34+
| Filename encryption | AES-256-SIV (RFC 5297) | Deterministic, so the same plaintext name maps to the same ciphertext and the scope stays listable |
35+
| Config integrity | HKDF-SHA256 key-bound MAC | On the `.aeroftp-crypt.json` config, over the version, block size, Argon2 profile (memory, time, lanes) and salt |
36+
37+
Each content block is laid out as `nonce(12) ‖ AES-256-GCM-SIV(DEK, plaintext_block, AAD) ‖ tag(16)`, where the AAD binds the block index **and** the total block count. The total block count is also carried, authenticated, in the file header.
38+
39+
### Hardened in v4.0.5 (pre-release audit)
40+
41+
A five-reviewer pre-release audit of the native overlay closed two live data-loss and downgrade classes, and the format was bumped to v3:
42+
43+
- **Per-file length binding.** Every block binds its index and the total block count; silent truncation (a dropped tail or whole blocks) and append (trailing bytes or extra blocks) now fail closed instead of returning short or padded plaintext.
44+
- **Key-bound config MAC.** The `.aeroftp-crypt.json` config carries an HKDF-SHA256 MAC bound to the master key. A tampered or downgraded config is rejected on unlock, and a wrong password gives a clean error instead of an empty listing.
45+
- **Init refuses to clobber.** `crypt init` will not overwrite an existing overlay config unless forced, because re-initialising rotates the salt and would orphan every file already in the overlay.
46+
- **Empty crypt password rejected**, and the decrypted plaintext download is written atomically.
47+
- **Legacy formats are read-only.** Existing v1 and v2 overlays keep decrypting transparently, but every new object is written as v3, so a stale or downgraded config can never produce weaker ciphertext. (v1 is the original plain AES-256-GCM with an HKDF per-file key and Argon2id-64; v2 is GCM-SIV without the length binding.)
48+
49+
## AeroCrypt vs rclone crypt vs AeroVault
50+
51+
AeroCrypt (native overlay), rclone crypt (interop overlay) and AeroVault (container) are three distinct things. Keep them apart:
52+
53+
| | AeroCrypt (native) | Rclone Crypt (interop) | AeroVault (container) |
54+
| --- | --- | --- | --- |
55+
| Shape | Per-file overlay on any provider | Per-file overlay, rclone's own format | Single sealed `.aerovault` file |
56+
| Content cipher | AES-256-GCM-SIV (nonce-misuse resistant) | XSalsa20-Poly1305 (not nonce-misuse resistant) | AES-256-GCM-SIV |
57+
| Filenames | AES-256-SIV | rclone EME | Kept inside the encrypted manifest |
58+
| Interop | AeroFTP only | Reads and writes rclone's format | AeroFTP (plus Cryptomator import) |
59+
| Best for | Leading encryption on any backend | Existing `rclone crypt` remotes | A sealed, portable bundle |
60+
61+
AeroFTP leads with AeroCrypt and keeps [Rclone Crypt](/features/rclone-crypt) beside it as the labelled interop lane, the same way [AeroVault](/security/encryption) sits beside Cryptomator import: support the foreign format, lead with ours. The nonce-misuse resistance of AES-256-GCM-SIV is the property rclone crypt's stream-cipher construction does not give you, which is why AeroCrypt leans on it.
62+
63+
## CLI
64+
65+
The `crypt` subcommand drives the same overlay from the terminal:
66+
67+
```bash
68+
# initialize an encrypted overlay at /encrypted on the S3 profile
69+
AEROFTP_CRYPT_PASSWORD=secret aeroftp-cli --profile "S3" crypt init _ /encrypted
70+
71+
# upload (content and filename encrypted)
72+
AEROFTP_CRYPT_PASSWORD=secret aeroftp-cli --profile "S3" crypt put ./secret.pdf _ /encrypted
73+
74+
# list (decrypted names visible)
75+
AEROFTP_CRYPT_PASSWORD=secret aeroftp-cli --profile "S3" crypt ls _ /encrypted
76+
77+
# download and decrypt
78+
AEROFTP_CRYPT_PASSWORD=secret aeroftp-cli --profile "S3" crypt get secret.pdf _ /encrypted ./out.pdf
79+
```
80+
81+
See [CLI Commands](/cli/commands) for the full `crypt` surface.
82+
83+
## Where AeroCrypt sits
84+
85+
AeroCrypt is the `crypt` wrapper of the AeroFTP overlay stack, applied per object on top of the provider. For the full layered encryption architecture see [Encryption](/security/encryption), and for the recovery layer that protects bytes against rot see [Error Correction](/security/error-correction).

features/aerovault.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -155,7 +155,7 @@ AeroVault files are registered as a MIME type on all platforms with dedicated ic
155155

156156
AeroVault v2 (described above) is the stable default. Two newer formats extend it without breaking it.
157157

158-
**v3 (Experimental)** is the first wrapper-stack vault. It keeps the single-file `.aerovault` portability of v2 while adding content-defined chunking (Gear-CDC), per-chunk zstd compression, deduplication, and a forward-compatible extension directory. The write pipeline is chunk-first: chunk → keyed-BLAKE3 chunk id → zstd → AES-256-GCM-SIV → BLAKE3-256 cipher hash. It is gated behind the Experimental tier in the vault-create dialog; v2 stays the default and there is no automatic migration.
158+
**v3 (the `Archive` tier)** is the first wrapper-stack vault. It keeps the single-file `.aerovault` portability of v2 while adding content-defined chunking (Gear-CDC), per-chunk zstd compression, deduplication, and a forward-compatible extension directory. The write pipeline is chunk-first: chunk → keyed-BLAKE3 chunk id → zstd → AES-256-GCM-SIV → BLAKE3-256 cipher hash. It ships as the `Archive` security tier in the vault-create dialog; the simpler Standard, Advanced and Paranoid tiers stay on v2, and there is no automatic migration.
159159

160160
**v4 = v3 + Error Correction.** v4 adds a fourth wrapper, Reed-Solomon parity, as a non-critical extension, so `v3 + ECC = v4` and a v3-only reader skips the parity it does not understand and still opens the container.
161161

security/encryption.md

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,9 @@ AeroFTP applies encryption across several distinct layers:
99
| Layer | Purpose | Primary Algorithm |
1010
| ----- | ------- | ----------------- |
1111
| AeroVault v2 | Stable encrypted file containers (default) | AES-256-GCM-SIV (RFC 8452) |
12-
| AeroVault v3 (Experimental) | Wrapper-stack container with content-defined chunking, dedup and per-chunk zstd | AES-256-GCM-SIV (RFC 8452) over zstd chunks |
13-
| AeroVault v4 error correction | Detached `.aerocorrect` recovery sidecar over the ciphertext (repair, not confidentiality) | Reed-Solomon parity, SHA-256 content binding |
14-
| AeroFTP-Crypt overlay | Streaming per-file encryption on top of any provider profile | AES-256-GCM with HKDF-derived per-file keys |
12+
| AeroVault v3 (Archive tier) | Wrapper-stack container with content-defined chunking, dedup and per-chunk zstd | AES-256-GCM-SIV (RFC 8452) over zstd chunks |
13+
| AeroVault v4 (v3 + error correction) | v3 container plus a detached `.aerocorrect` recovery sidecar over the ciphertext (repair, not confidentiality) | Reed-Solomon parity, SHA-256 content binding |
14+
| AeroCrypt overlay (native) | Per-file encryption on top of any provider profile (`AECR` format) | AES-256-GCM-SIV content, AES-256-KW DEK wrap, AES-256-SIV filenames |
1515
| Archive encryption | Password-protected ZIP/7z | AES-256 |
1616
| rclone crypt interoperability | Compatibility decryption for existing remotes | XSalsa20-Poly1305 content + standard filename decryption |
1717
| Credential storage | vault.db secrets | AES-256-GCM + Argon2id |
@@ -87,9 +87,9 @@ The key derivation parameters exceed OWASP 2024 minimum recommendations:
8787

8888
AeroFTP can also create and browse Cryptomator vault format 8 containers, using scrypt + AES-256-KW + AES-256-SIV + AES-256-GCM.
8989

90-
## AeroVault v3 (Experimental)
90+
## AeroVault v3 (Archive tier)
9191

92-
AeroVault v3 is the first wrapper-stack vault format. It keeps the single-file `.aerovault` portability of v2 while adding content-defined chunking, per-chunk zstd compression, deduplication, and a forward-compatible extension directory shaped around the future v4 ECC (error-correction) layer. The format is implementation-draft and gated behind the Experimental security tier in the vault-create dialog. v2 remains the default and there is no automatic v2 → v3 migration until v3 leaves Experimental.
92+
AeroVault v3 is the first wrapper-stack vault format. It keeps the single-file `.aerovault` portability of v2 while adding content-defined chunking, per-chunk zstd compression, deduplication, and a forward-compatible extension directory used by the v4 error-correction layer. It ships as the **`Archive`** security tier in the vault-create dialog (the simpler Standard, Advanced and Paranoid tiers stay on v2), after its public spec review pass in the [#276 design thread](https://github.com/axpdev-lab/aeroftp/discussions/276). v2 remains the default for the other tiers and there is no automatic v2 → v3 migration.
9393

9494
The canonical reference is the in-repo specification at [`docs/AEROVAULT-V3-SPEC.md`](https://github.com/axpdev-lab/aeroftp/blob/main/docs/AEROVAULT-V3-SPEC.md).
9595

@@ -179,24 +179,24 @@ AeroVault v3 uses AES-256-GCM-SIV by default. The wrapper stack is designed so t
179179

180180
### Tauri command surface
181181

182-
Fifteen Tauri commands cover the v3 lifecycle and are exposed once the Experimental tier is selected: `vault_v3_create`, `vault_v3_open`, `vault_v3_add_files`, `vault_v3_add_files_to_dir`, `vault_v3_create_directory`, `vault_v3_extract_entry`, `vault_v3_delete_entry`, `vault_v3_delete_entries`, `vault_v3_move_entry`, `vault_v3_rename_entry`, `vault_v3_copy_entry`, `vault_v3_change_password`, `vault_v3_add_directory`, `vault_v3_security_info`, `is_vault_v3`.
182+
Fifteen Tauri commands cover the v3 lifecycle and are exposed via the `Archive` tier: `vault_v3_create`, `vault_v3_open`, `vault_v3_add_files`, `vault_v3_add_files_to_dir`, `vault_v3_create_directory`, `vault_v3_extract_entry`, `vault_v3_delete_entry`, `vault_v3_delete_entries`, `vault_v3_move_entry`, `vault_v3_rename_entry`, `vault_v3_copy_entry`, `vault_v3_change_password`, `vault_v3_add_directory`, `vault_v3_security_info`, `is_vault_v3`.
183183

184-
## AeroVault container vs AeroFTP-Crypt overlay
184+
## AeroVault container vs AeroCrypt overlay
185185

186-
AeroVault and AeroFTP-Crypt are two different shapes for two different needs, and the choice between them depends on whether you want a sealed object or an ongoing transformation.
186+
AeroVault and AeroCrypt are two different shapes for two different needs, and the choice between them depends on whether you want a sealed object or an ongoing transformation. They are not the same thing: AeroVault is a container, AeroCrypt is a per-file overlay. See [AeroCrypt Overlay](/features/aerocrypt) for the full overlay guide.
187187

188-
| Property | AeroVault (`.aerovault`) | AeroFTP-Crypt overlay |
189-
| -------- | ------------------------ | --------------------- |
190-
| Shape | Single sealed file, OS-integrated MIME type, double-clickable | Streaming per-file overlay on top of any provider profile |
188+
| Property | AeroVault (`.aerovault`) | AeroCrypt overlay |
189+
| -------- | ------------------------ | ----------------- |
190+
| Shape | Single sealed file, OS-integrated MIME type, double-clickable | Per-file overlay on top of any provider profile |
191191
| Granularity | Whole-container operation, manifest indexes all entries | Per-file: each remote object is independently encrypted |
192192
| Best for | Sharing several files as one bundle (email, instant messenger, USB stick, cold-storage snapshot) | Ongoing folder mirror on a provider you do not trust at rest |
193-
| Visibility | Browseable in AeroFTP and (for v3) addressable through the vault commands | Cleartext through an AeroMount mount; encrypted blobs if you open the underlying provider panel directly |
193+
| Visibility | Browseable in AeroFTP and (for v3) addressable through the vault commands | Browsed like a normal server in the dual panel once unlocked; encrypted blobs if you open the underlying provider panel directly |
194194
| Single-file aspect | Yes (the load-bearing feature) | No |
195-
| Format owner | AeroFTP (v2 and v3 specs) | AeroFTP (CLI-defined `.aeroftp-crypt.json` config + per-file AES-256-GCM with HKDF-derived keys) |
195+
| Format owner | AeroFTP (v2 and v3 specs) | AeroFTP (`AECR` format: per-file AES-256-GCM-SIV under a random DEK wrapped with AES-256-KW, AES-256-SIV filenames, `.aeroftp-crypt.json` config with a key-bound MAC) |
196196

197-
The mental model: if the question is "send a sealed bundle to one person" or "shelve a snapshot on portable media", that is AeroVault. If the question is "keep this folder continuously mirrored on kDrive but the server must never see plaintext", that is the AeroFTP-Crypt overlay. The two coexist on purpose.
197+
The mental model: if the question is "send a sealed bundle to one person" or "shelve a snapshot on portable media", that is AeroVault. If the question is "keep this folder continuously mirrored on kDrive but the server must never see plaintext", that is the AeroCrypt overlay. The two coexist on purpose. There is no default cipher: you actively pick AeroCrypt (native) or [Rclone Crypt](/features/rclone-crypt) (interop).
198198

199-
Cipher-strength badges in the connection UI follow this distinction: `E2E 128-bit` / `E2E 256-bit` for providers whose vendor performs client-side end-to-end encryption (MEGA, Filen, Internxt), and a plain `128-bit` / `256-bit` (no `E2E` prefix) for AeroFTP-Crypt overlaid on a server-side-encrypted backend, because the server holds no key but the cipher is ours, not the vendor's.
199+
Cipher-strength badges in the connection UI follow this distinction: `E2E 128-bit` / `E2E 256-bit` for providers whose vendor performs client-side end-to-end encryption (MEGA, Filen, Internxt), and a plain `128-bit` / `256-bit` (no `E2E` prefix) for AeroCrypt overlaid on a server-side-encrypted backend, because the server holds no key but the cipher is ours, not the vendor's.
200200

201201
## rclone crypt interoperability
202202

0 commit comments

Comments
 (0)