CipherFS
In Entwicklung · unveröffentlicht · Format kann sich ändern

Clientseitig verschlüsselte Dateisynchronisation ohne vertrauenswürdigen Server

Dateien werden verschlüsselt, bevor sie das Gerät verlassen. Geräte synchronisieren sich direkt miteinander oder über alles, was Bytes ablegen kann: ein S3-Bucket, ein lokaler Ordner, ein Verzeichnis, das iCloud oder Dropbox transportiert. Keiner davon sieht Dateinamen oder Inhalte, und keiner braucht Sperren oder atomare Updates.

In Rust geschrieben. CLI, FUSE-Mount, Web-Oberfläche sowie C-, Python- und Go-Bindings.

Was der Speicher sieht

i/d7a1…/000412-9f3c…-18204
i/2b90…/000098-71e0…-6112
p/3f/3f8a…-6291456
p/c2/c2d4…-5833728
n/0007-e41b…-2097152
r/d7a1…-epoch3

Was ein Gerät sieht

docs/
  contract-2026.pdf        2 Versionen
  notes.md                 2 Konflikt-Heads
photos/
  2026-09/IMG_4471.heic    beim Lesen geholt
projects/cipherfs/
  README.md
Papierkorb: old-drafts/ (14 Dateien)

Links: Objektnamen aus Geräte-ID, Sequenznummer, Länge und Chiffrat-Hash. Rechts: der Dateibaum, den ein Gerät nach dem Entschlüsseln zeigt, mit Versionszahlen, Konflikten und Papierkorb. Zwischen beiden gibt es keinen Server.

Entwurf

Was es verspricht

Clientseitige Verschlüsselung

Inhalte, Dateinamen und sensible Metadaten werden verschlüsselt, bevor sie das Gerät verlassen. Lesen prüft die Integrität; ein falsches Passwort, Manipulation oder Beschädigung schlagen deutlich fehl. Schlüssel und Klartext erreichen weder Logs noch Speicher.

Zuverlässige Synchronisation

Offline-Änderungen werden synchronisiert, sobald wieder Verbindung besteht. Unterbrochene Übertragungen werden wiederholt, und eine wiederholte Übertragung wendet nie eine alte Version erneut an oder belebt sie wieder. Gleichzeitige Änderungen bestimmen die aktuelle Version nach einer Regel; jede andere Version bleibt erhalten.

Kleine wie große Dateien

Kleine Dateien bleiben günstig. Große Dateien werden in Blöcke zerlegt, gestreamt und nach Byte-Bereich geholt. Niemand wählt einen Modus, und das Überschreiten einer Größenschwelle ändert nie die Semantik.

Kern und Adapter

Verschlüsselung, Dateimodell, Speichertransaktionen und Synchronisationsregeln liegen im Kern. CLI, Mount, Web-Oberfläche und Sprach-Bindings passen nur den Zugriff an. Sie führen keine eigene Datenbank und erfinden keine Regeln.

Vollständiger Index, optionale Inhalte

Jedes Gerät hält den vollständigen gemeinsamen Index. Inhalte werden standardmäßig auf jedes Gerät synchronisiert; ein Telefon oder ein Laptop mit wenig Platz kann ein Teilgerät sein, das nur angeheftete Ordner und kürzlich Gelesenes behält.

Kein vertrauenswürdiger Server

Geräte verbinden sich direkt miteinander. Speicher halten nur Chiffrat-Objekte. Verlauf, Papierkorb und Konflikte sind Sichten auf eine gemeinsame Versionskette, auf jedem Gerät sichtbar. Jedes Gerät hat eine eigene Identität und kann widerrufen werden.

Modell

Verlauf, Papierkorb und Konflikte sind dieselbe Kette

Jede Datei hat eine stabile Identität; ihr Pfad ist nur ein Attribut. Jedes Gerät hängt an sein eigenes signiertes Log an, und andere Geräte prüfen Mitgliedschaft, Hash-Kette und kausale Abhängigkeiten, bevor sie zusammenführen. Ein Löschen ist eine Tombstone-Version, ein Verschieben eine Version mit neuem Pfad, ein Konflikt sind zwei oder mehr Heads ohne kausale Ordnung.

v1 notes.md Gerät A 09-28 14:02 v2 notes.md Gerät A 10-01 09:15 ← Verlauf v3 notes.md Gerät B 10-03 22:40 ← Head (aktuell) v3' notes.md Gerät C 10-03 22:41 ← Head (Konflikt) v4 Eltern = v3, v3' ← ein Gerät, das beide Heads gesehen hat, schreibt; der Konflikt endet

Verzeichnisse und Mounts zeigen nur die aktuelle Version; Konfliktkopien werden nicht geschrieben. Eine Version verlässt den gemeinsamen Verlauf nur durch ein explizites Löschen oder die Aufbewahrungsrichtlinie des Repositories (standardmäßig 365 Tage). Zuerst bleibt sie 30 Tage im Wartezustand, in dem jedes Gerät abbrechen kann.

Bestandteile

Geräte, Speicher, Schlüssel

Geräte

Clients, die die Repository-Schlüssel halten und Klartext lesen. Jedes hat ein langlebiges Schlüsselpaar, einen lesbaren Namen und die Rolle Voll oder Teil. Ein neues Gerät koppelt sich mit einem kurzen Code oder QR-Code; ohne vorhandenes Gerät tritt es mit dem Wiederherstellungsschlüssel bei.

Speicher

Brauchen nur vier Operationen: unveränderliches Objekt schreiben, nach Name lesen, nach Präfix auflisten, löschen. Objekte sind inhaltsadressiert und nur anhängend, gepackt zu 4 bis 8 MiB. Ein noch nicht vollständig angekommenes Objekt gilt als „noch nicht da“, nie als „beschädigt“.

Schlüssel

Inhaltsschlüssel leiten sich aus einer Schlüsselepoche ab. Das Widerrufen eines Geräts eröffnet eine neue Epoche, deren Schlüssel nur für die verbleibenden Geräte verpackt wird. Das Passwort schützt nur den lokalen Rechner; ein vergessenes Passwort wird mit dem Wiederherstellungsschlüssel zurückgesetzt, und das Gerät behält seine Identität.

Szenario

Kalte Dateien vom Mac auslagern

Ein dauerhaft laufender Rechner ist das Vollgerät. Der Mac ist ein Teilgerät mit Mount. Er behält nur angeheftete Ordner und kürzlich gelesene Inhalte; alles andere erscheint weiterhin im Finder und wird beim Öffnen vom Vollgerät oder einem Speicher geholt. Über dem Cache-Budget werden Inhalte, die nachweislich anderswo existieren, automatisch freigegeben. Unsynchronisierte lokale Schreibvorgänge und offene Dateien werden nie freigegeben.

Geprüft auf macOS 27 mit FUSE-T: Der Mount trägt .metadata_never_index, ist von Time Machine ausgeschlossen, das Durchblättern aller Ordner im Finder ließ den Cache unverändert, und das Lesen einer nicht verfügbaren Datei im Offline-Zustand schlägt sofort fehl, statt zu hängen.

Stand

Ist es reif für eine Veröffentlichung?

Nicht als stabile Version. Die bestätigten Anforderungen sind umgesetzt und jede hat Abnahmebelege, aber das Datenformat und die API dürfen sich noch ändern, es gab kein externes Sicherheitsaudit, und ein Kompatibilitätsversprechen wurde nie gegeben. Heute eignet es sich für den Autor und wenige Personen, die Formatänderungen akzeptieren.

Prüfergebnisse mit Stand 12. Oktober 2026. Die Zahlen sind tatsächliche Ausführungen je Feature-Kombination.

PrüfungErgebnis
Rust-Tests auf dem Host, Standard-Features672 bestanden / 0 fehlgeschlagenbestanden
Rust-Tests auf dem Host, alle Features700 bestanden / 0 fehlgeschlagenbestanden
Container-Lauf, Rust754 bestanden / 0 fehlgeschlagen / 2 ignoriertbestanden
C-Laufzeit / Python / Go race15 / 10 / gesamtes Paketbestanden
Frontend-Build, Web-Smoke-Test24 Prüfungenbestanden
Echter FUSE-T-Teil-Mount, Finder-DurchsichtCache 54.288 → 54.288 Bbestanden
Abnahmematrix der AnforderungenR01–R62 auf Tests abgebildeterledigt

Noch offen

Einstieg

Kommandozeile

Das Passwort kommt aus CIPHERFS_PASSWORD oder einer interaktiven Abfrage. S3-Zugangsdaten werden aus Umgebungsvariablen gelesen und nie in den gemeinsamen Index geschrieben.

cipherfs init --path ~/vault
cipherfs put --vault ~/vault --source ./notes.txt --target docs/notes.txt
cipherfs store add directory --vault ~/vault --dir ~/Library/CloudStorage/Dropbox/cfs
cipherfs sync directory --vault ~/vault --store-dir ~/Library/CloudStorage/Dropbox/cfs

cipherfs role set partial --vault ~/vault --read-cache-bytes 2147483648
cipherfs pin add --vault ~/vault --path docs
cipherfs mount --vault ~/vault --mount-point ~/CipherFS --background

cipherfs devices list --vault ~/vault
cipherfs safe-to-remove --vault ~/vault
cipherfs history --vault ~/vault --path docs/notes.txt
cipherfs export --vault ~/vault --target ~/plain-copy --history

Rust-Anwendungen verwenden SyncedVault: put, put_from_reader, get, get_to_writer, get_range, delete, list. Ein erfolgreiches Schreiben bedeutet, dass die Daten lokal dauerhaft gespeichert sind; eine Hintergrundaufgabe übernimmt Synchronisation, Wiederverbindung und Wiederholungen. Der Speicherbedarf hängt nicht von der Objektgröße ab.

Voreinstellungen

Algorithmen

ZweckAlgorithmus
Inhalts-AEADXChaCha20-Poly1305 (optional AES-256-GCM, ChaCha20-Poly1305)
BlockbildungFastCDC, min/avg/max 1 / 4 / 8 MiB, Einheit höchstens 16 MiB
InhaltsadressierungBLAKE3
Geräteidentitäted25519-Signaturen, X25519-Verpackung, zugleich P2P-Knoten-ID
Lokales PasswortArgon2id verpackt lokales Schlüsselmaterial; wird nie synchronisiert
TransportQUIC (Iroh); HTTPS zu Speichern nach Bedarf