Ihr Passwort verlässt Ihr Gerät nie: So funktioniert die Anmeldung
Ein Passwort beweist, wer Sie sind, und entsperrt Ihre Schlüssel. Erledigt ein Geheimnis beides, sieht der Server den Schlüssel zu Ihren Dateien. Wie Sapherbox aus einem Passwort zwei Schlüssel macht.
Jedes Ende-zu-Ende-verschlüsselte Produkt fragt Sie nach einem Passwort. Und dieses Passwort hat zwei Aufgaben, die sich widersprechen.
Die erste Aufgabe: Es beweist dem Server, dass Sie es sind. Dafür bekommen Sie eine Sitzung und dürfen Ihre (verschlüsselten) Dateien abrufen. Für diese Aufgabe muss der Server etwas prüfen, das Sie ihm schicken.
Die zweite Aufgabe: Es entsperrt Ihre Schlüssel. In Sapherbox wird Ihr Passwort auf Ihrem Gerät in den Schlüssel verwandelt, der Ihren Account Master Key öffnet. Von dort aus geht es weiter zu jedem Datei-, Ordner- und Gruppenschlüssel, auf den Sie Zugriff haben. Für diese Aufgabe darf der Server nie etwas sehen, womit sich dieses Entsperren nachvollziehen ließe.
Erledigt ein einziges Geheimnis beide Aufgaben, verliert die zweite. Was Sie zur Anmeldung schicken, ist dann genau das, was Ihre Schlüssel öffnet. Ein Server, der kompromittiert wurde, eine behördliche Anordnung erhält oder schlicht neugierig ist, kann es behalten. Die meisten Produkte mit „Zero Knowledge“ im Prospekt haben diese Lücke irgendwo. Es lohnt sich, jeden Anbieter zu fragen, wohin das Passwort geht.
Dieser Artikel erklärt, wie Sapherbox jeder Aufgabe ihr eigenes Geheimnis gibt. Beide entstehen aus dem einen Passwort, das Sie eintippen. Und das, was der Server prüft, kann nichts öffnen.
Zwei Schlüssel aus einem Passwort
Wenn Sie Ihr Passwort eingeben, tut Ihr Browser (oder der Sync-Client oder die Mac-App) der Reihe nach Folgendes.
Schritt 1: eine langsame Schlüsselableitung. Das Passwort und ein zufälliges Salt, das bei der Registrierung erzeugt wurde, gehen in Argon2id. Das ist eine absichtlich aufwendige Funktion. Sie belegt 64 MB Speicher und läuft in drei Durchgängen. Auf Ihrem Gerät dauert das einen Bruchteil einer Sekunde. Wer Passwörter in großem Stil durchprobieren will, braucht dafür Jahre. Das Ergebnis ist ein 256-Bit-Wert, den wir Wrap-Schlüssel nennen. Er ist der Schlüssel, der Ihren Account Master Key auspackt. Er bleibt auf Ihrem Gerät, immer.
Schritt 2: ein Einwegschritt. Der Wrap-Schlüssel geht durch HKDF, eine standardisierte Ableitungsfunktion, mit einem festen Label. Heraus kommt ein zweiter 256-Bit-Wert, der Anmeldeschlüssel. Nur dieser wird an den Server geschickt.
Entscheidend ist die Richtung der Pfeile. Der Wrap-Schlüssel erzeugt den Anmeldeschlüssel, aber der Anmeldeschlüssel lässt sich nicht in den Wrap-Schlüssel zurückrechnen. HKDF baut auf SHA-256 auf, und es umzukehren ist so schwer, wie den Hash umzukehren. Wer den Anmeldeschlüssel kennt, weiß nichts über den Schlüssel, der Ihre Dateien öffnet.
Passwort + Salt --Argon2id--> Wrap-Schlüssel (öffnet den Master Key, bleibt auf dem Gerät)
Wrap-Schlüssel --HKDF-----> Anmeldeschlüssel (geht an den Server, beweist Ihre Identität)
Schritt 3: Der Server prüft den Anmeldeschlüssel. Auch den speichert er nicht. Er speichert einen Argon2id-Hash davon, mit eigenem Salt, genau so, wie ein gut betriebener Dienst Passwort-Hashes speichert. Bei der Anmeldung hasht er, was Sie geschickt haben, und vergleicht.
Davor gibt es noch einen kleinen Schritt. Der Client fragt den Server zuerst nach Salt und Argon2id-Parametern des Kontos, denn ohne sie kann er nichts ableiten. Für eine E-Mail-Adresse ohne Konto antwortet der Server mit einer stabilen, echt aussehenden Attrappe. So lässt sich über diese Anfrage nicht herausfinden, welche Adressen registriert sind.
Was Sie davon haben
Sehen wir uns an, was nach diesem Entwurf jede Seite in der Hand hält.
Ihr Gerät hält das Passwort für einen Moment, den Wrap-Schlüssel, solange Sie entsperrt sind, und den Anmeldeschlüssel für die Dauer einer einzigen Anfrage.
Der Server hält einen Hash des Anmeldeschlüssels, den Master Key verpackt unter dem Wrap-Schlüssel und die Identitätsschlüssel verpackt unter dem Master Key. Drei verschlossene Boxen und der Fingerabdruck eines Schlüssels, der keine davon öffnet.
Betrachten wir also die Fälle, die einen Sicherheitsprüfer interessieren:
- Eine Kopie unserer Datenbank wird gestohlen. Der Angreifer bekommt gehashte Anmeldeschlüssel. Jeder Anmeldeschlüssel besteht aus 256 zufällig wirkenden Bits, also gibt es nichts zu raten. Der Hash ist eine Sackgasse. Die verpackten Master Keys sind AES-GCM-Chiffrat unter Schlüsseln, die der Angreifer nicht hat. Ihre Dateien bleiben zu.
- Der laufende Server wird kompromittiert. Ein Angreifer im Server sieht Anmeldeschlüssel ankommen. Damit kann er sich gegenüber der API als Nutzer ausgeben und Chiffrat herunterladen. Das ist schlimm, und genau dafür ist das Audit-Protokoll da. Aber er kann keine einzige Datei entschlüsseln. Vor der Trennung hätte dieselbe Position das Passwort geliefert, und damit den Wrap-Schlüssel.
- Ein böswilliger Betreiber. Also wir, oder jemand mit unserem Zugang. Dieselbe Antwort. Wir haben das System so gebaut, dass man uns nicht nach Ihrem Passwort fragen kann, weil wir es nie erhalten.
Ein Nebeneffekt, der erwähnt werden sollte: Die Passwortregeln werden jetzt auf Ihrem Gerät geprüft, bevor etwas abgeleitet wird. Der Server kann nicht kontrollieren, ob ein neues Passwort einen Großbuchstaben enthält, denn er sieht nur noch einen Schlüssel. Der Client holt sich die Richtlinie des Tenants. Lässt sie sich nicht laden, bricht er ab, statt die Regeln stillschweigend zu lockern.
Was Sie davon nicht haben
Wir veröffentlichen unsere Grenzen. Hier sind die, die hier gelten.
Der Code auf Ihrem Gerät sieht das Passwort. Das lässt sich nicht vermeiden. Irgendetwas muss Argon2id ausführen. Die Frage ist, ob Sie dem Client trauen können, den Sie erhalten haben. Bei der Web-App heißt das: dem Code vertrauen, den wir ausliefern, geschützt durch TLS und eine strikte Content Security Policy. Bei den Desktop- und Mac-Clients heißt es: signierte und notarisierte Builds. Die Auslieferung des Clients ist der Teil der Vertrauenskette, bei dem wir Ihnen noch am meisten schulden. Das sagen wir auch in unserem Bedrohungsmodell.
Ein abgefischtes Passwort bleibt ein abgefischtes Passwort. Tippen Sie es auf einer Seite ein, die nicht Sapherbox ist, hilft die Trennung nicht. Passkeys helfen: Eine Anmeldung mit Passkey kommt ganz ohne Passwort aus und ist an unsere Domain gebunden. Wenn Sie können, nutzen Sie einen.
Ein kompromittiertes Gerät ist das Ende. Wrap-Schlüssel und Master Key liegen auf Ihrem Gerät, solange Sie entsperrt sind. Schadsoftware dort liest Ihre Dateien wie Sie selbst. Daran ändert kein Verschlüsselungsentwurf etwas. Deshalb versuchen wir nicht, den Endgeräteschutz zu ersetzen, sondern ergänzen ihn: Wir arbeiten mit führenden Anbietern für Endpoint Security zusammen, damit unsere Kunden Sapherbox mit dem Geräteschutz kombinieren können, den sie ohnehin einsetzen.
Einführung ohne Passwort-Reset
Jetzt zum unangenehmen Teil der Technik. Am Tag, an dem die Trennung live ging, lag für jedes bestehende Konto ein Hash des Klartext-Passworts auf dem Server. Der Server kann daraus keine Hashes von Anmeldeschlüsseln machen, denn er hat die Wrap-Schlüssel nicht. Alle Nutzer durch einen Passwort-Reset zu schicken, kam ebenfalls nicht in Frage.
Die Lösung ist eine Umstellung bei der Anmeldung. Jedes Konto trägt eine kleine Markierung, nach welchem Schema sein gespeicherter Hash gebildet wurde. Wenn ein Client vor der Anmeldung nach dem Salt fragt, sagt der Server auch, auf welchem Schema das Konto steht. Ein Konto nach altem Schema schickt sein Passwort ein letztes Mal, über TLS. Der Server prüft es gegen den alten Hash, leitet dieses eine Mal selbst den Anmeldeschlüssel ab, speichert den neuen Hash und nimmt das Passwort nie wieder an. Ab der nächsten Anmeldung zählt nur noch der Anmeldeschlüssel.
Denselben Mechanismus haben wir eine Woche später ein zweites Mal genutzt, als aus dem Produkt Sapherbox wurde und das HKDF-Label vom alten auf den neuen Namen wechselte. Auch diese Hashes kann ein Server nicht umrechnen. Ein Client, der ein Konto mit altem Label vorfindet, schickt deshalb den alten und den neuen Anmeldeschlüssel. Sobald der alte geprüft ist, ersetzt ihn der neue. Niemand wurde abgemeldet, niemand musste etwas zurücksetzen.
Alle drei Clients, die Web-App, der Sync-Client und die Mac-App, leiten den Schlüssel auf dieselbe Weise ab. Ein gemeinsamer Testvektor in jeder Codebasis stellt sicher, dass sie Byte für Byte übereinstimmen. Wer nachrechnen möchte:
Passwort "correct horse battery staple"
Salt 00 01 02 … 1f (32 Byte)
Argon2id m = 65536 KiB, t = 3, p = 4, 32 Byte Ausgabe
HKDF SHA-256, leeres Salt, Info "sapherbox-login-v1", 32 Byte Ausgabe
Anmeldeschlüssel s4U3a+VCYzwCj8xmwk4VelMMrZsd7TANEmm1PYf2sAg= (Base64)
Fragen?
Möchte Ihr Sicherheitsteam die vollständige Ableitung und die serverseitige Prüfung an einem Ort nachlesen? Das Dokument zum Verschlüsselungsablauf hinter diesem Artikel stellen wir auf Anfrage bereit: hello@sapherbox.com.