Zusammenspiel

Client und Server

Was Client und Server jeweils wissen dürfen, ist beim "Cautiously Knowing Service" bereits beschrieben. Aber wie funktioniert dieses Zusammenspiel in der Praxis?

Beispiel Schlüsselwechsel: Der Server weiß, wie alt der aktuelle Hauptschlüssel ist, und teilt dem Client nach der Anmeldung mit, ob dieser gewechselt werden sollte.

Der Client kennt zu diesem Zeitpunkt noch das Hauptkennwort, erstellt einen neuen SCrypt-Hash als Ausgangpunkt für die neue Schlüsselableitung. Der SCrypt-Hash enthält zum einen Daten über die geforderte Stärke der Schlüsselstreckung (diese wurden vorab vom Server dem Client mitgeteilt), aber auch eine zufällige Bytefolge, die bewirkt, dass jede neue Schlüsselableitung von der alten verschieden ist. Mit dem abgeleiteten Schlüssel (dem "Vor-Schlüssel") wird dann ein komplett zufällig gewählter neuer Hauptschlüssel verschlüsselt. (Dieses Verfahren hat den Vorteil, dass bei einer Kennwortänderung, nur der Vor-Schlüssel und der damit verschlüsselte Hauptschlüssel neu zu berechnen sind, während der Klartext des Hauptschlüssels unverändert bleibt, also auch alle damit verschlüsselten Werte unberührt bleiben.)

Sowohl Client als auch Server dürfen den neuen SCrypt-Hash kennen, aber nur der Client kennt das Hauptkennwort, und daher kann nur er den neuen Hauptschlüssel aus diesen beiden Komponenten berechnen.

Alle Geheimnisse einer Box sind mit einem Hauptschlüssel verschlüsselt. Nicht ganz direkt: Jedes Geheimnis hat einen Datenschlüssel, und dieser ist mit dem Hauptschlüssel verschlüsselt. Die Daten selbst (genauer die Kerngeheimnisse) sind mit dem Datenschlüssel verschlüsselt.

In der Datenbank (die vom Server verwaltet wird) werden "Schlüsselsets" für Boxen abgelegt. In einem solchen liegt der SCrypt-Hash, aber auch ein Hauptschlüssel. Der Server kann damit (zumindest im Endausbau des Cautiously Knowing Service) nicht mehr anfangen, als diese Daten dem Client zur Verfügung zu stellen.

Es kann also mehrere Hauptschlüssel geben. Nur einer von Ihnen ist dagegen der neueste, der sog. "Default-Hauptschlüssel", alle sind mit dem gleichen Vor-Schlüssel verschlüsselt, der von dem SCrypt-Hash und dem momentanen Hauptkennwort abgeleitet wird.

Da alle Hauptschlüssel mit dem gleichen Vor-Schlüssel verschlüsselt werden, kommt der Client auch an die älteren Hauptschlüssel heran ohne neue Schlüsselstreckung. Das ist wichtig, weil die Datenschlüssel der einzelnen Geheimnisse nach einem Schlüsselwechsel, der im Erstellen eine neuen "Default-Hauptschlüssels" besteht, sich dann zunächst auf einen älteren Hauptschlüssel beziehen. Um das zu bereinigen, werden die Datenschlüssel dann auf den neuen Default-Hauptschlüssel umgeschlüsselt.

Dass beim Anmelden nur einmal eine Schlüsselstreckung passiert, ist wichtig, da die der Benutzer*in zumutbare Zeit nicht verschwendet werden sollte, sondern so voll in die Schlüsselstreckung und damit Stärke des Default-Hauptschlüssels investiert werden kann.

Wie ist also die Aufgabenverteilung zwischen Client und Server? Der Server holt die verschlüsselten Daten aus der Datenbank und sendet sie an den Client. Vom Client bearbeitete Daten (umgeschlüsselt oder neu verschlüsselt) sendet dieser an den Server und lässt sie in der Datenbank speichern.

Damit der Client alle nötigen Schlüssel auch für die gesamte Sitzung zur Verfügung hat (d. h. an deren Klartexte herankommen kann), muss er sie im Web-Speicher des Browsers verschlüsselt zwischenspeichern. Der Server kann hier helfen, indem er für den Client einen der beiden Schlüssel dafür in seinen Sitzungsdaten verwahrt und diesem bei jedem Seitenwechsel neu mitteilt. Da der Server die Sitzungsdaten im Web-Speicher nicht kennt, könnte er selbst mit dem verwahrten Schlüssel nichts anfangen.

Sender und Empfänger

"Sender" und "Empfänger" sind hier technisch gemeint, aber dahinter stehen auch Personen, die Besitzer*innen von Boxen (und manchmal auch von Gruppencontainern).

Beispiel "Übertragung eines Notfallkoffers": Ein Notfallkoffer ist ein Geheimnis, in dem das aktuelle Hauptkennwort (oder ein Teil davon) der sendenden Box befindet. Es wird an eine oder mehrere Empfangsboxen gesendet.

Der Server holt dazu die verschlüsselten Daten aus der Datenbank: Das verschlüsselte Hauptkennwort (im Notfallkoffer), den verschlüsselten Datenschlüssel für den Notfallkoffer, die ID des zugehörigen Schlüsselsets, die IDs von bereits übertragenen (zu aktualisierenden) Gegenstücken bei den Empfangsboxen und die zugehörigen die öffentlichen Schlüssel, die sich in den Schlüsselsets der Empfangsboxen befinden.

Diese Daten sendet der Server an den Client. Dieser holt den Klartext aus dem verschlüsselten Hauptkennwort, verschlüsselt die zu übertragenen Teile mit den öffentlichen Schlüsseln und sendet alle nötigen Daten an den Server, der dann die Erstellung bzw. Aktualisierung der Empfangs-Geheimnisse vornehmen kann, ohne irgendeinen Schlüssel oder gar Hauptkennwortteil im Klartext zu kennen.

Die Sache ist noch etwas schwieriger, weil Notfallkoffer in der Regel versiegelt sind. Ein Siegel ist ein zusätzlicher Schlüssel mit dem der Datenschlüssel in den empfangenen Boxen verschlüsselt wird.

Wird ein Siegelbruch durchgeführt, so sind an diesem Prozess die Besitzer*in der sendenden Box, die der empfangenden Box und die Logik des key.matiq-Dienstes beteiligt. Letztendlich steuert der Server den Schlüssel für Siegelbruch bei. Dieser Schlüssel liegt im Klartext in der Datenbank, da eine Verschlüsselung durch Sender oder Empfänger keinen Sinn macht: Es liegt in der Natur der Sache, dass das Siegel eines Notfallkoffers gerade dann gebrochen wird, wenn die Besitzer*in der sendenden Box auf letztere nicht mehr zugreifen kann, also das für eine Entschlüsselung notwendige Hauptkennwort nicht mehr eingegeben werden kann. Und eine Verschlüsselung des Siegels durch eine Empfänger-Box bringt keinen zusätzlichen Nutzen (der Datenschlüssel ist ohnehin durch einen Hauptschlüssel gesichert).

Also kann hier der Server direkt den Siegelbruch durch Entschlüsselung des versiegelten Datenschlüssels vornehmen, sobald die Voraussetzungen (Antrag auf Siegelbruch, Versuch der Benachrichtigung der Besitzer*in der sendenden Box, Ablauf der Karenzzeit) gegeben sind.

Hinterlegungen und Hinterlegungsstellen

Hier ist die Situation ähnlich beim versiegelten Notfallkoffer, nur dass es hier nicht um Siegelbruch geht, sondern um die evtl. Rückgabe des Hauptkennworts.

Ein Hinterleger versendet das Hauptkennwort jedesmal, wenn es geändert wurde, an die Hinterlegungsstellen. Für solch einen Versand wird ein "Versand-Objekt" erstellt. Auch dieses merkt sich einen Extra-Schlüssel (ähnlich wie das Siegel), erstellt aber auch für jede Hinterlegung einen Hinterlegungsschlüssel. Hinterlegungsschlüssel und Extra-Schlüssel werden miteinander kombiniert und bilden zusammen den "Komplett-Schlüssel", mit dem das zu hinterlegende Hauptkennwort-Teil verschlüsselt wird.

An die Hinterlegungsstelle werden als Hinterlegung-Daten geschickt: Hinterlegungs-Schlüssel (verschlüsselt mit dem öffentlichen Schlüssel der Hinterlegungsstelle) und der verschlüsselte Hauptkennwort-Teil.

Die Verschlüsselung wird auf dem Client des Hinterlegers vorgenommen. Er darf alle dafür notwendigen Daten im Klartext kennen. Es sind schließlich, bis auf den öffentlichen Schlüssel der Hinterlegungstelle, nur eigene Daten. Die verschlüsselten Daten werden in der Datenbank durch den Server abgelegt.

Wichtig ist, dass in den abzuspeichernden Hinterlegungs-Daten der Extra-Schlüssel nicht auftaucht, sondern dieser im Versand-Objekt verbleibt (im Klartext, aus den gleichen Gründen wie oben beim Siegel).

Der Grund ist: Für die Hinterlegungsstellen werden täglich Backups gezogen, die von deren Besitzer*innen auch heruntergeladen werden können. Es darf für diese nicht möglich sein, die empfangenen Hauptkennwort-Teile zu entschlüsseln. Dafür fehlt ihnen der Extra-Schlüssel.

Hinterlegungsstellen und Tickets

Die Rückgabe von Hauptkennwörtern erfolgt an Tickets. Nehmen wir an, ein Ticket wurde erstellt und geprüft und bewilligt. Dann sollten die Hinterlegungsstellen die Hinterlegungen an das Ticket schicken, damit dessen Besitzer*in die Hauptkennworte mit den Hinterlegungszeiten im Klartext abrufen kann.

Hier kommt wieder der Extra-Schlüssel ins Spiel. Die Hinterlegungsstellen senden einfach die verschlüsselten Hauptkennwortteile an das Ticket und die zugehörigen Hinterlegungschlüssel (natürlich nicht offen, sondern verschlüsselt mit dem öffentlichen RSA-Schlüssel des Tickets).

Im Client des Tickets wird nun die Entschlüsselung vorgenommen. Den dafür noch nötigen Extra-Schlüssel kann der Server beisteuern, da er ihn unverschlüsselt aus der Datenbank holen kann.

Eine Angreifer*in, die es schaffen würde, auf die Datenbank zuzugreifen, hätte mit dem Extra-Schlüssel alleine nichts gewonnen, außer diese Person wäre Besitzer*in einer Hinterlegungsstelle. D. h. hier müssten schon zwei Unfälle zusammenkommen, um Schlimmes zu bewirken: Der Einbruch müsste geschehen und die Besitzer*in eines Hinterlegers müsste just dieser Einbrecher*in fälschlich vertrauen.

Extra Schlüssel für jeden Zweck ...

Für jeden neuen Versand wird ein neuer Extra-Schlüssel und für jede Hinterlegung ein neuer Hinterlegungsschlüssel erstellt. Denn theoretisch kann die Besitzer*in eines Tickets die JavaScripts des Clients manipulieren, so dass sie darüber die Werte von Extra-Schlüssel und Hinterlegungsschlüssel mitlesen kann. Die damit entschlüsselten Werte erfährt sie ohnehin, und daher wäre das nicht schlimm.

Schlimm wäre es aber, wenn diese Schlüssel auch weiterhin gebraucht würden.

Stellen wir uns z. B. vor, es würde sich nachträglich herausstellen, dass die Ticket-Besiter*in eine Betrüger*in wäre. Wir würden der tatsächlichen Eigentümer*in die Box wieder zurückgeben und helfen den Schaden zu begrenzen.

In einem solchen Fall könnte sich es als fatal herausstellen, wenn weiterhin mit denselben Schlüsseln (die nun ja auch die Betrüger*in kennen würde) Hinterlegungen vorgenommen werden. Dann hätte die Betrüger*in nach wie vor einen Fuss in der Tür, wohl ohne dass es jemand sofort merken würde.

Das ist natürlich ein sehr theoretischer Fall, aber genau so denken Hacker*innen, versuchen theoretische Lücken zu finden, um diese für sich praktikabel zu weiten und schließlich in erfolgreichen Angriffen einzusetzen.

Mit frischen Schlüsseln bei einem neuen Versand ist jedenfalls der obige theoretische Fall ausgeschlossen.

... auch bei Geheimnissen

Auch bei Geheimnissen achten wir auf einen häufigen Schlüsselwechsel: Wann immer der Inhalt geändert wird, wird auch ein neuer Datenschlüssel erstellt. Vorteil ist: Wir können damit bei Geheimnissen, die übertragen werden, den gleichen Datenschlüssel für das gesendete Geheimnis, wie für die empfangenen Geheimnisse verwenden. Die verschlüsselten Daten sind für das zu sendende Geheimnis und die empfangsseitig zu erstellenden Geheimnisse völlig gleich und können rein serverseitig kopiert werden. Lediglich der Datenschlüssel muss für jede Empfangs-Box mit derem öffentlichem Schlüssel verschlüsselt werden. Das spart Zeit und Ressourcen.

Da sich der Datenschlüssel auf nur exakt eine Version der Daten bezieht, und auch für nichts anderes hergenommen wird, ist das möglich, ohne die Sicherheit zu gefährden.

Ein Kompass, wer was wissen darf

Die obigen Beispiele zeigen auf, dass wir einen Kompass haben:

Wir überlegen bei Client und Server genau, was jeder von beiden wissen darf oder auch nicht. Der Client darf z. B. nur Daten von der eigenen Box, oder nötige unkritische Daten von anderen Boxen (z. B. öffentliche Schlüssel) kennen. Der Server soll nach Implementation des Cautiously Knowing Service nur noch in (genehmigten) Ausnahmefällen Daten entschlüsseln können.

Wir schauen auch bei der Übertragung von Schlüsseln und Geheimnissen sehr genau darauf, was Sende- und Empfangsseite wissen dürfen und was nicht.

Wir dürfen uns auch nicht in eine Pseudosicherheit in Form von unnötigen Restriktionen verirren: Es macht z. B. überhaupt keinen Sinn, jemand an der Wiederherstellung eines gelöschten empfangenen Geheimnisses zu hindern, wenn sie oder er sich dieses schon einmal angeschaut haben. Warum sollte jemand dies nicht über einzuspielendes Backup wiederbekommen können? Würden wir solche Möglichkeiten nicht bieten, würde es nur dazu führen, dass Nutzer*innen sich selbst unsichere Backups in Form von Screenshots oder schriftlichen Notizen erstellen würden.