[{"data":1,"prerenderedAt":-1},["ShallowReactive",2],{"legal-e2ee-de":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"body":10,"_type":491,"_id":492,"_source":493,"_file":494,"_stem":495,"_extension":496},"\u002Flegal\u002Fe2ee\u002Fde","e2ee",false,"","So funktioniert unsere Ende-zu-Ende-Verschlüsselung","Stand: Juni 2026",{"type":11,"children":12,"toc":480},"root",[13,21,26,33,58,64,69,74,78,84,89,143,149,177,197,209,213,223,229,241,253,258,264,276,288,292,298,303,374,380],{"type":14,"tag":15,"props":16,"children":18},"element","h1",{"id":17},"so-funktioniert-unsere-ende-zu-ende-verschlüsselung",[19],{"type":20,"value":8},"text",{"type":14,"tag":22,"props":23,"children":24},"p",{},[25],{"type":20,"value":9},{"type":14,"tag":27,"props":28,"children":30},"h2",{"id":29},"kurz-gesagt",[31],{"type":20,"value":32},"Kurz gesagt",{"type":14,"tag":34,"props":35,"children":36},"ul",{},[37,43,48,53],{"type":14,"tag":38,"props":39,"children":40},"li",{},[41],{"type":20,"value":42},"Deine Daten werden auf deinem Gerät verschlüsselt und verlassen es nur als unlesbarer Chiffretext. Unser Server speichert ausschließlich verschlüsselte Blobs und hat keinen Zugriff auf den Klartext.",{"type":14,"tag":38,"props":44,"children":45},{},[46],{"type":20,"value":47},"Alle Schlüssel werden aus einem 128-Bit-Recovery-Code abgeleitet, der dein Gerät nie verlässt. Wir kennen ihn nicht und können ihn nicht wiederherstellen.",{"type":14,"tag":38,"props":49,"children":50},{},[51],{"type":20,"value":52},"Jeder einzelne Record wird mit einem eigenen Schlüssel verschlüsselt und vor der Entschlüsselung auf Echtheit geprüft (Verify-before-Decrypt mit Ed25519).",{"type":14,"tag":38,"props":54,"children":55},{},[56],{"type":20,"value":57},"E2EE schützt nicht alles: Bestimmte Metadaten (Datenmenge, Zugriffszeiten) bleiben sichtbar, und ein kompromittiertes Gerät oder ein verlorener Recovery-Code lässt sich nicht durch Kryptographie retten.",{"type":14,"tag":27,"props":59,"children":61},{"id":60},"was-ende-zu-ende-bei-uns-bedeutet",[62],{"type":20,"value":63},"Was „Ende-zu-Ende\" bei uns bedeutet",{"type":14,"tag":22,"props":65,"children":66},{},[67],{"type":20,"value":68},"Ende-zu-Ende-Verschlüsselung heißt: Der Klartext deiner Daten existiert nur auf deinen eigenen Geräten. Die Ver- und Entschlüsselung passiert ausschließlich lokal. Was zwischen Geräten synchronisiert und auf unserem Server abgelegt wird, ist immer schon verschlüsselt, bevor es das Gerät verlässt.",{"type":14,"tag":22,"props":70,"children":71},{},[72],{"type":20,"value":73},"Konkret: Eine Datenzeile wird auf dem Client kanonisch zu JSON kodiert und dann mit einem AEAD-Verfahren verschlüsselt. Der Server empfängt nur einen opaken Byte-Blob plus einige Verwaltungsfelder. Er besitzt keinen der Schlüssel, die zum Entschlüsseln nötig wären. Das ist eine architektonische Eigenschaft, kein Versprechen: Da die Schlüssel das Gerät nie erreichen, kann der Server den Inhalt technisch nicht lesen.",{"type":14,"tag":75,"props":76,"children":77},"e2ee-flow-diagram",{},[],{"type":14,"tag":27,"props":79,"children":81},{"id":80},"wie-deine-daten-verschlüsselt-werden",[82],{"type":20,"value":83},"Wie deine Daten verschlüsselt werden",{"type":14,"tag":22,"props":85,"children":86},{},[87],{"type":20,"value":88},"Wir verwenden bewährte, standardisierte Bausteine aus den Bibliotheken @noble\u002Fciphers, @noble\u002Fhashes und @noble\u002Fcurves:",{"type":14,"tag":34,"props":90,"children":91},{},[92,103,113,123,133],{"type":14,"tag":38,"props":93,"children":94},{},[95,101],{"type":14,"tag":96,"props":97,"children":98},"strong",{},[99],{"type":20,"value":100},"AES-256-GCM",{"type":20,"value":102}," verschlüsselt deine Records. AES-256-GCM ist ein AEAD-Verfahren, das gleichzeitig Vertraulichkeit (niemand liest mit) und Integrität (Manipulation fällt auf) sichert. Jeder Record nutzt eine zufällige 12-Byte-Nonce und einen 16-Byte-Authentifizierungscode (MAC). Format: nonce(12) ‖ ciphertext ‖ mac(16).",{"type":14,"tag":38,"props":104,"children":105},{},[106,111],{"type":14,"tag":96,"props":107,"children":108},{},[109],{"type":20,"value":110},"XChaCha20-Poly1305",{"type":20,"value":112}," verschlüsselt das Schlüsselmaterial beim Geräte-Pairing (Key-Wrapping). Es ist ebenfalls ein AEAD-Verfahren, nutzt aber eine längere 24-Byte-Nonce, was zufällige Nonces unkritisch macht.",{"type":14,"tag":38,"props":114,"children":115},{},[116,121],{"type":14,"tag":96,"props":117,"children":118},{},[119],{"type":20,"value":120},"AAD (Associated Data)",{"type":20,"value":122}," bindet jeden Chiffretext an seine Metadaten — Header, Bucket, Record-UUID, Revision, Key-Epoch, Schema-Version und paddierte Länge. Diese Felder sind mitauthentifiziert: Wird auch nur eines verändert, schlägt die Entschlüsselung fehl. Leere AAD wird hart abgelehnt (Confused-Deputy-Schutz).",{"type":14,"tag":38,"props":124,"children":125},{},[126,131],{"type":14,"tag":96,"props":127,"children":128},{},[129],{"type":20,"value":130},"Padding",{"type":20,"value":132}," verschleiert die genaue Größe: Jeder Record wird auf eine Bucket-Größe aufgefüllt (256, 1024, 4096, 16384 oder 65536 Bytes; darüber Vielfache von 65536). So verrät die Blob-Größe nur eine grobe Klasse, nicht die exakte Datenmenge.",{"type":14,"tag":38,"props":134,"children":135},{},[136,141],{"type":14,"tag":96,"props":137,"children":138},{},[139],{"type":20,"value":140},"Ed25519-Signatur (blob_sig)",{"type":20,"value":142}," signiert jeden Blob. Vor jeder Entschlüsselung prüft der Client diese Signatur gegen die autorisierten Geräteschlüssel (Verify-before-Decrypt). Die Prüfung läuft RFC-8032-strikt (zip215:false), was Fälschungen über Low-Order-Punkte ausschließt. Manipulierte Daten ergeben sofort einen Fehler, keinen stillen Defekt.",{"type":14,"tag":27,"props":144,"children":146},{"id":145},"deine-schlüssel-bleiben-auf-deinem-gerät",[147],{"type":20,"value":148},"Deine Schlüssel bleiben auf deinem Gerät",{"type":14,"tag":22,"props":150,"children":151},{},[152,154,159,161,166,168,175],{"type":20,"value":153},"Die Wurzel von allem ist eine ",{"type":14,"tag":96,"props":155,"children":156},{},[157],{"type":20,"value":158},"128-Bit-Recovery-Entropie",{"type":20,"value":160}," — der Recovery-Code. Aus diesen 16 zufälligen Bytes wird mit ",{"type":14,"tag":96,"props":162,"children":163},{},[164],{"type":20,"value":165},"HKDF-SHA256",{"type":20,"value":167}," (eine Schlüsselableitungsfunktion, die aus einem Geheimnis viele domänengetrennte Schlüssel erzeugt) deterministisch ein Master-Secret abgeleitet und daraus weitere Schlüssel: eine Account-ID, ein Key-Encryption-Key, der Auth-Schlüssel (authSeed) und der Routing-Schlüssel. Jede Ableitung nutzt ein eigenes, versioniertes Label (z. B. ",{"type":14,"tag":169,"props":170,"children":172},"code",{"className":171},[],[173],{"type":20,"value":174},"mypep\u002Fmaster\u002Fv1",{"type":20,"value":176},"), sodass sich die Schlüssel nicht überschneiden.",{"type":14,"tag":22,"props":178,"children":179},{},[180,182,187,189,195],{"type":20,"value":181},"Pro Collection gibt es einen eigenen Collection-Key, und ",{"type":14,"tag":96,"props":183,"children":184},{},[185],{"type":20,"value":186},"pro Record und Revision",{"type":20,"value":188}," einen eigenen Record-Key (",{"type":14,"tag":169,"props":190,"children":192},{"className":191},[],[193],{"type":20,"value":194},"rec\u002F\u003Cuuid>\u002F\u003Crev>",{"type":20,"value":196},"). Dieser eigene Schlüssel je (Record, Revision) sorgt für eine vollständige Schlüssel-Trennung: Kein AES-GCM-Schlüssel wird je zweimal verwendet — ein starker Schutz gegen Nonce-Reuse-Angriffe.",{"type":14,"tag":22,"props":198,"children":199},{},[200,202,207],{"type":20,"value":201},"Das Master-Secret wird bewusst ",{"type":14,"tag":96,"props":203,"children":204},{},[205],{"type":20,"value":206},"nicht gespeichert",{"type":20,"value":208},". Lokal liegen nur die abgeleiteten Werte und die geräteeigenen Signier-\u002FWrap-Schlüssel — im Browser in IndexedDB.",{"type":14,"tag":210,"props":211,"children":212},"key-derivation-diagram",{},[],{"type":14,"tag":22,"props":214,"children":215},{},[216,221],{"type":14,"tag":96,"props":217,"children":218},{},[219],{"type":20,"value":220},"Recovery — Feature und Verantwortung:",{"type":20,"value":222}," Der gesamte Schlüsselbaum hängt am Recovery-Code. Wir speichern ihn nicht; eine Hintertür, ein Key-Escrow oder ein serverseitiger Reset sind architektonisch ausgeschlossen — nicht nur per Richtlinie, sondern weil die Schlüssel den Server technisch nie erreichen. Das ist der Kern echter E2EE: Niemand außer dir — auch wir nicht — kann deine Daten ohne den Recovery-Code oder ein gepairtes Gerät wiederherstellen. Geht der Code verloren und existiert kein gekoppeltes Gerät mehr, sind die Daten endgültig unzugänglich.",{"type":14,"tag":27,"props":224,"children":226},{"id":225},"was-unser-server-sieht-und-was-nicht",[227],{"type":20,"value":228},"Was unser Server sieht — und was nicht",{"type":14,"tag":22,"props":230,"children":231},{},[232,234,239],{"type":20,"value":233},"Der Server speichert nur verschlüsselte Blobs. Er sieht ",{"type":14,"tag":96,"props":235,"children":236},{},[237],{"type":20,"value":238},"nicht",{"type":20,"value":240},": den Inhalt deiner Records, die Namen deiner Collections (sie erscheinen nur als opaker HMAC-SHA256-Bucket) oder deine Schlüssel.",{"type":14,"tag":22,"props":242,"children":243},{},[244,246,251],{"type":20,"value":245},"Ehrlich gesagt sieht er aber ",{"type":14,"tag":96,"props":247,"children":248},{},[249],{"type":20,"value":250},"einige Metadaten",{"type":20,"value":252},": die opaken Bucket-Werte, die Record-Revisionen, die grobe Größenklasse über das Padding, die Synchronisations-Häufigkeit, Geräte-IDs (als SHA-256-Hash der Geräteschlüssel) und die Cursor-Position beim Abgleich. Daraus lässt sich ableiten, dass ein Account aktiv ist und ungefähr wie viele bzw. wie große Daten wann bewegt werden — nicht aber, worum es inhaltlich geht.",{"type":14,"tag":22,"props":254,"children":255},{},[256],{"type":20,"value":257},"Die Konfliktauflösung läuft rein über Revisionen (höhere Revision gewinnt, „Last-Write-Wins\"), weil der Server den Inhalt nicht kennt und nicht inhaltlich zusammenführen kann. Authentifizierung erfolgt per Challenge-Response mit Ed25519 und einem anschließenden JWT-Token; die Device-Liste wird mit deinem Auth-Schlüssel signiert und ausschließlich clientseitig verifiziert.",{"type":14,"tag":27,"props":259,"children":261},{"id":260},"mehrere-geräte-pairing",[262],{"type":20,"value":263},"Mehrere Geräte (Pairing)",{"type":14,"tag":22,"props":265,"children":266},{},[267,269,274],{"type":20,"value":268},"Ein neues Gerät, etwa der Browser, wird per ",{"type":14,"tag":96,"props":270,"children":271},{},[272],{"type":20,"value":273},"QR-Code mit dem Phone gekoppelt",{"type":20,"value":275},". Der QR überträgt die öffentlichen Geräteschlüssel des Browsers direkt (out-of-band), nicht über den Server — das schützt den Schlüsseltausch vor Man-in-the-Middle-Angriffen. Das Phone verpackt das Identity-Bundle (Account-Daten-Schlüssel, Auth-Schlüssel, Account-ID, Routing-Schlüssel) per X25519-ECDH und XChaCha20-Poly1305 ausschließlich für den Browser und überträgt es verschlüsselt.",{"type":14,"tag":22,"props":277,"children":278},{},[279,281,286],{"type":20,"value":280},"Nach dem Entschlüsseln zeigt der Browser einen ",{"type":14,"tag":96,"props":282,"children":283},{},[284],{"type":20,"value":285},"Fingerprint",{"type":20,"value":287}," (SHA-256 der Account-ID, als Hex-Gruppen). Stimmt er mit der Anzeige auf dem Phone überein, ist sichergestellt, dass du das richtige Bundle empfangen hast. Web-Clients haben keinen eigenen Recovery-Code: Bei Verlust des Browser-Speichers koppelst du einfach erneut mit dem Phone.",{"type":14,"tag":289,"props":290,"children":291},"pairing-diagram",{},[],{"type":14,"tag":27,"props":293,"children":295},{"id":294},"was-das-nicht-schützt",[296],{"type":20,"value":297},"Was das NICHT schützt",{"type":14,"tag":22,"props":299,"children":300},{},[301],{"type":20,"value":302},"E2EE ist stark, aber kein Allheilmittel. Ehrlich zu den Grenzen:",{"type":14,"tag":34,"props":304,"children":305},{},[306,316,326,336,354,364],{"type":14,"tag":38,"props":307,"children":308},{},[309,314],{"type":14,"tag":96,"props":310,"children":311},{},[312],{"type":20,"value":313},"Kompromittiertes Gerät:",{"type":20,"value":315}," Schadsoftware im Browser-Kontext oder direkter Zugriff auf IndexedDB kann die lokal gespeicherten Schlüssel lesen und damit alles entschlüsseln. Die lokale Datenbank liegt im Klartext vor.",{"type":14,"tag":38,"props":317,"children":318},{},[319,324],{"type":14,"tag":96,"props":320,"children":321},{},[322],{"type":20,"value":323},"Verlorener Recovery-Code:",{"type":20,"value":325}," Ohne Code und ohne gekoppeltes Gerät gibt es keinen Weg zurück. Es existiert keine Schlüsselrotation und kein Backup-Mechanismus.",{"type":14,"tag":38,"props":327,"children":328},{},[329,334],{"type":14,"tag":96,"props":330,"children":331},{},[332],{"type":20,"value":333},"Metadaten:",{"type":20,"value":335}," Datenmengen, Größenklassen, Zugriffsmuster und Zeitpunkte bleiben für den Server sichtbar.",{"type":14,"tag":38,"props":337,"children":338},{},[339,344,346,352],{"type":14,"tag":96,"props":340,"children":341},{},[342],{"type":20,"value":343},"Foto-Blobs:",{"type":20,"value":345}," Fotos sind content-adressiert (",{"type":14,"tag":169,"props":347,"children":349},{"className":348},[],[350],{"type":20,"value":351},"blob_id = sha256(blob)",{"type":20,"value":353},"). Wer einen Klartext bereits besitzt, kann prüfen, ob genau dieses Foto hochgeladen wurde.",{"type":14,"tag":38,"props":355,"children":356},{},[357,362],{"type":14,"tag":96,"props":358,"children":359},{},[360],{"type":20,"value":361},"Bösartiger Server:",{"type":20,"value":363}," Er kann den Inhalt nicht lesen oder fälschen (Verify-before-Decrypt schützt), aber er könnte Daten zurückhalten oder alte signierte Device-Listen erneut ausliefern (Replay). Der Schaden eines solchen Replays ist begrenzt: Das Gerät registriert sich idempotent, sodass eine zurückgespielte alte Liste den aktuellen Zustand nicht überschreibt. Neue gültige Daten erfinden kann der Server nicht.",{"type":14,"tag":38,"props":365,"children":366},{},[367,372],{"type":14,"tag":96,"props":368,"children":369},{},[370],{"type":20,"value":371},"Auth-Schlüssel:",{"type":20,"value":373}," Wer den Auth-Schlüssel erlangt, kann die Device-Liste ändern und sich re-authentifizieren. Er muss geheim bleiben.",{"type":14,"tag":27,"props":375,"children":377},{"id":376},"die-kryptographischen-bausteine-im-überblick",[378],{"type":20,"value":379},"Die kryptographischen Bausteine im Überblick",{"type":14,"tag":34,"props":381,"children":382},{},[383,392,401,411,420,430,440,450,460,470],{"type":14,"tag":38,"props":384,"children":385},{},[386,390],{"type":14,"tag":96,"props":387,"children":388},{},[389],{"type":20,"value":100},{"type":20,"value":391}," — Record-Verschlüsselung (AEAD); 12-Byte-Nonce, 16-Byte-MAC.",{"type":14,"tag":38,"props":393,"children":394},{},[395,399],{"type":14,"tag":96,"props":396,"children":397},{},[398],{"type":20,"value":110},{"type":20,"value":400}," — Key-Wrapping beim Pairing (AEAD); 24-Byte-Nonce, 16-Byte-MAC.",{"type":14,"tag":38,"props":402,"children":403},{},[404,409],{"type":14,"tag":96,"props":405,"children":406},{},[407],{"type":20,"value":408},"Argon2id v1.3",{"type":20,"value":410}," — passwortbasierte, speicherharte Ableitung (Standard: 64 MiB, 3 Iterationen, 4 Lanes); verfügbar für künftige passwortbasierte Funktionen, aber NICHT für den Recovery-Code — der ist bereits 128 Bit Zufallsentropie und braucht keine Speicher-Härte.",{"type":14,"tag":38,"props":412,"children":413},{},[414,418],{"type":14,"tag":96,"props":415,"children":416},{},[417],{"type":20,"value":165},{"type":20,"value":419}," — Ableitung aller Schlüssel aus dem Recovery-Code, domänengetrennt über versionierte Labels; 32-Byte-Output.",{"type":14,"tag":38,"props":421,"children":422},{},[423,428],{"type":14,"tag":96,"props":424,"children":425},{},[426],{"type":20,"value":427},"HMAC-SHA256",{"type":20,"value":429}," — opakes Routing der Collections (Bucket-Berechnung).",{"type":14,"tag":38,"props":431,"children":432},{},[433,438],{"type":14,"tag":96,"props":434,"children":435},{},[436],{"type":20,"value":437},"SHA-256",{"type":20,"value":439}," — Hashing für Fingerprints, Geräte-IDs und Foto-Adressierung.",{"type":14,"tag":38,"props":441,"children":442},{},[443,448],{"type":14,"tag":96,"props":444,"children":445},{},[446],{"type":20,"value":447},"Ed25519 (RFC-8032-strikt, zip215:false)",{"type":20,"value":449}," — Signaturen für Records, Device-Liste und Authentifizierung.",{"type":14,"tag":38,"props":451,"children":452},{},[453,458],{"type":14,"tag":96,"props":454,"children":455},{},[456],{"type":20,"value":457},"X25519-ECDH",{"type":20,"value":459}," — Schlüsselaustausch beim Geräte-Pairing.",{"type":14,"tag":38,"props":461,"children":462},{},[463,468],{"type":14,"tag":96,"props":464,"children":465},{},[466],{"type":20,"value":467},"Padding-Buckets",{"type":20,"value":469}," (256 B bis 65536 B, darüber Vielfache von 65536) — Größenverschleierung.",{"type":14,"tag":38,"props":471,"children":472},{},[473,478],{"type":14,"tag":96,"props":474,"children":475},{},[476],{"type":20,"value":477},"Schlüssellänge",{"type":20,"value":479}," durchgehend 32 Bytes (256 Bit).",{"title":7,"searchDepth":481,"depth":481,"links":482},2,[483,484,485,486,487,488,489,490],{"id":29,"depth":481,"text":32},{"id":60,"depth":481,"text":63},{"id":80,"depth":481,"text":83},{"id":145,"depth":481,"text":148},{"id":225,"depth":481,"text":228},{"id":260,"depth":481,"text":263},{"id":294,"depth":481,"text":297},{"id":376,"depth":481,"text":379},"markdown","content:legal:e2ee:de.md","content","legal\u002Fe2ee\u002Fde.md","legal\u002Fe2ee\u002Fde","md"]