Passwörter sind ein Problem. Die meisten Menschen, die Passwörter benutzen, sind sich der Gründe dieser Probleme allerdings nicht bewusst. Ein Passwort, das Ihren Kontrollbereich verlässt, opfert garantiert die Sicherheit, egal wie komplex oder wie schwer es zu erraten ist.

Die Mehrheit der Leser wird sofort zustimmen, dass Passwörter schwer zu merken und zu verwalten sind, zumal die Anforderungen an Passwörter immer komplexer werden. Glücklicherweise gibt es großartige Softwarepakete und Browser-Add-ons, die bei der Verwaltung von Passwörtern helfen. Die Mehrheit der Leser wird jedoch überrascht sein zu erfahren, dass die Probleme viel tiefer liegen, als allgemein bekannt ist. Sie alle liegen darin begründet, dass Passwörter von Natur aus unsicher sind.

Vielleicht entgegnen Sie jetzt „aber Passwörter werden immer in verschlüsseltem Format gespeichert!“. Das ist richtig, aber nur die halbe Wahrheit. Die Wahrheit ist, dass selbst ein verschlüsseltes Passwort geknackt werden kann, wenn auch (und glücklicherweise) nur mit enormem Aufwand, sofern es ordentlich verschlüsselt ist. Ein immer drängenderes Problem ergibt sich aus der Natur der Passwörter selbst: Um ein Passwort direkt verwenden zu können, muss das Passwort im Klartext verarbeitet werden.

Jetzt meinen Sie „Aber mein Passwort wird sicher über HTTPS übertragen!“ Das ist wahr.

Sie meinen: „Aber ich weiß, dass der Server mein Passwort in verschlüsselter Form speichert, sicher, so dass niemand darauf zugreifen kann!“ Nun, damit setzen Sie eine Menge Vertrauen in den Server. Trotzdem, sagen wir einfach, ja, das mag auch stimmen.

Es bleibt jedoch ein wichtiger Vorbehalt - eine Schwachstelle in der End-to-End-Verwendung von Passwörtern. Bedenken Sie, dass das Passwort, sobald ein Server ein Passwort erhält, zwischen sicherer Übertragung und sicherer Speicherung gelesen und verarbeitet werden muss. Ja, als Klartext!

Und es wird noch schlimmer - weil so viele daran gewöhnt sind, in Software zu denken, ist es leicht, die Verwundbarkeit der Hardware zu vergessen. Das heißt, selbst wenn die Software irgendwie vertrauenswürdig ist, muss sich das Passwort irgendwann im Speicher befinden. Das Passwort muss irgendwann über einen gemeinsamen Bus an die CPU übertragen werden. Diese bieten Beobachtern Angriffsvektoren in vielen Formen. Natürlich sind diese Angriffsvektoren weitaus unwahrscheinlicher als jene, die sich durch Übertragung und permanente Speicherung ergeben, aber sie sind nicht weniger schwerwiegend (die jüngsten CPU-Schwachstellen wie Spectre und Meltdown sollten als eindringliche Warnung dienen).

Die einzige Möglichkeit, dieses Problem zu beheben, besteht darin, Passwörter gänzlich abzuschaffen. Es gibt Hoffnung! Die Forschung und Arbeitsgruppen im privaten Sektor arbeiten hart daran, genau dies zu erreichen. Neue Standards entstehen und werden immer ausgereifter. Leider sind Passwörter so allgegenwärtig, dass es sehr lange dauern wird, bis man sich auf neue Standards und Technologien einigen wird und Passwörter verdrängen kann.

Bei Cloudflare haben wir uns gefragt, ob es etwas gibt, das jetzt, in Kürze, getan werden kann. Der heutige Deep-Dive in OPAQUE ist eine mögliche Antwort. OPAQUE ist eines von vielen Beispielen für Systeme, die es ermöglichen, dass ein Passwort nützlich sein kann, ohne dass es jemals Ihren Besitz verlässt. Niemand mag Passwörter, aber solange sie in Gebrauch sind, können wir zumindest sicherstellen, dass sie nie weitergegeben werden.

Ich bin die Erste, die zugibt, dass passwortbasierte Authentifizierung lästig ist: Passwörter sind schwer zu merken, mühsam einzugeben und notorisch unsicher. Initiativen zur Reduzierung oder Ersetzung von Passwörtern sind vielversprechend. So ist etwa WebAuthn ein Standard für die Web-Authentifizierung, der hauptsächlich auf Public Key Cryptography (PKC) unter Verwendung von Hardware- (oder Software-)Token basiert. Trotzdem ist der Einsatz von Passwörtern als Authentifizierungsmechanismus frustrierend beständig. Unabhängig davon, ob ihre Beständigkeit darauf zurückzuführen ist, dass sie einfach zu implementieren sind, Nutzer damit vertraut sind oder im Internet schlichtweg allgegenwärtig sind: Solange die passwortbasierte Authentifizierung im Einsatz ist, möchten wir sie so sicher wie möglich machen.

Im Mittelpunkt meines Praktikums bei Cloudflare stand OPAQUE, ein kryptographisches Protokoll, das eines der eklatantesten Sicherheitsprobleme bei passwortbasierter Authentifizierung löst: Obwohl Passwörter bei der Übertragung für gewöhnlich durch HTTPS geschützt sind, werden sie von Servern im Klartext verarbeitet, um ihre Richtigkeit zu überprüfen. Die Verarbeitung von Klartext-Passwörtern ist gefährlich, da ihre versehentliche Protokollierung oder Zwischenspeicherung zu einer katastrophalen Sicherheitsverletzung führen könnte. Das Ziel des Projekts ist es nicht, die Adoption eines bestimmten Protokolls voranzutreiben, sondern zu zeigen, dass OPAQUE eine von vielen praktikablen Optionen für die Authentifizierung ist. Da mir und wahrscheinlich vielen Lesern der Anwendungsfall im Internet am besten vertraut ist, werde ich primär das Internet als Anwendungsbeispiel nutzen.

Das 1x1 der Web-Authentifizierung: Passwort-via-TLS

Was passiert, wenn Sie im Web ein Passwort eingeben? Die Website muss überprüfen, ob das von Ihnen eingegebene Passwort mit dem Passwort übereinstimmt, mit dem Sie sich ursprünglich auf der Website registriert haben. Aber wie funktioniert diese Überprüfung?

Normalerweise werden Ihr Benutzername und Ihr Passwort an einen Server geschickt. Der Server überprüft dann, ob das Passwort, das er für Ihren Benutzernamen hinterlegt hat, mit dem von Ihnen angegebenen Passwort übereinstimmt. Um zu verhindern, dass ein Angreifer, der Ihren Internetverkehr ausspioniert, Ihr Passwort stehlen kann, sollte Ihre Verbindung zum Server natürlich über HTTPS (HTTP-over-TLS) [HTTPS] verschlüsselt werden.

Trotz der Nutzung von HTTPS, stehen wir in diesem Fluss vor einem großen Problem: Der Server muss irgendwo ein Abbild Ihres Passworts speichern. Server sind schwer zu sichern, und Sicherheitsverletzungen sind allzu häufig. Der Diebstahl dieses Abbilds kann katastrophale Sicherheitsprobleme verursachen. (Daten über die jüngsten Sicherheitsverletzungen finden Sie unter https://haveibeenpwned.com/).

Damit diese Datendiebstähle weniger verheerend wären, wenden Server oft eine Hash-Funktion auf Nutzerpasswörter an. Eine Hash-Funktion ordnet jedes Passwort einem eindeutigen, zufällig aussehenden Wert zu. Es ist einfach, den Hash auf ein Passwort anzuwenden, aber fast unmöglich, die Funktion umzukehren und auf das Passwort rückzuschließen. (Aber jeder kann ein Passwort erraten, die Hash-Funktion anwenden und überprüfen, ob das Ergebnis dasselbe ist.)

Beim Passwort-Hashing werden Klartext-Passwörter nicht mehr auf Servern gespeichert.  Ein Angreifer, der eine Passwort-Datenbank stiehlt, hat keinen direkten Zugriff mehr auf die Passwörter. Stattdessen muss der Angreifer nun den Hash auf viele mögliche Passwörter anwenden und die Ergebnisse mit den durchgesickerten Hashes vergleichen.

Hasht ein Server hingegen nur die Passwörter, so können Angreifer leider vorberechnete Regenbogentabellen (Rainbow Tables) herunterladen, die Hashes von Billionen möglicher Passwörter enthalten, und praktisch sofort auf die Klartext-Passwörter rückschließen. (Siehe https://project-rainbowcrack.com/table.htm für eine Liste einiger Regenbogentabellen).

Vor diesem Hintergrund besteht eine gute Verteidigungsstrategie darin, Hashing mit Salt zu verwenden, bei dem der Server Ihr Passwort als Anhang an einen zufälligen Wert pro Benutzer, einen so genannten Salt, hasht. Der Server speichert den Salt gemeinsam mit dem Benutzernamen, so dass der Benutzer ihn nie sieht oder übermitteln muss. Wenn der Benutzer ein Passwort eingibt, rechnet der Server diese Hash-Funktion mit Hilfe des Salts neu aus. Ein Angreifer, der Passwortdaten (d. h. die Passwortabbilder und Salt-Werte) stiehlt, muss dann beliebte Passwörter eines nach dem anderen erraten und die (Salted) Hash-Funktion auf jedes erratene Passwort anwenden. Vorhandene Regenbogentabellen helfen nicht weiter, da sie die Salts nicht berücksichtigen, sodass der Angreifer für jeden Benutzer eine neue Regenbogentabelle erstellen muss!

Dadurch wird der Angriff (hoffentlich) so weit verlangsamt, dass der Dienst die Nutzer über eine Sicherheitsverletzung informieren kann, sodass diese ihre Passwörter ändern können. Darüber hinaus sollten die Salted Hashes verstärkt werden, indem ein Hash viele Male angewendet wird, um die Angriffe weiter zu verlangsamen. (Siehe https://blog.cloudflare.com/keeping-passwords-safe-by-staying-up-to-date/ für eine ausführlichere Diskussion).

Diese beiden Abwehrstrategien -- die Verschlüsselung des Passworts während der Übertragung und die Speicherung verstärkter Salted Hashes -- sind derzeit die bewährtesten Verfahren.

Eine große Sicherheitslücke bleibt jedoch bestehen. Passwort-via-TLS (wie wir es bezeichnen werden) erfordert, dass Nutzer bei der Anmeldung Klartextpasswörter an Server senden, weil Server diese Passwörter sehen müssen, um es mit den registrierten gespeicherten Passwörtern abzugleichen. Selbst ein wohlmeinender Server könnte versehentlich Ihre Passwortversuche zwischenspeichern oder protokollieren oder bei der Überprüfung von Passwörtern manipuliert werden. (Beispielsweise stellte Facebook 2019 fest, dass es versehentlich mehrere Hundert Millionen Benutzerpasswörter in Form von Klartext gespeichert hatte). Im Idealfall sollten Server überhaupt nie ein Klartext-Passwort sehen.

Aber hier zeigt sich ein Dilemma: Wie kann man ein Passwort überprüfen, wenn man das Passwort nie sieht? Hier kommt OPAQUE: ein Password-Authenticated Key Exchange- (PAKE-)Protokoll, das gleichzeitig die Kenntnis eines Passworts nachweist und einen geheimen Schlüssel ableitet. Bevor wir OPAQUE im Detail beschreiben, fassen wir zunächst die Funktionalitäten von PAKE im Allgemeinen zusammen.

Passwort-Nachweise mit Password-Authenticated Key Exchange

Password-Authenticated Key Exchange (PAKE) wurde 1992 von Bellovin und Merrit[1] vorgeschlagen. Die ursprüngliche Motivation bestand darin, Passwortauthentifizierung ohne die Möglichkeit von Wörterbuchangriffen (Dictionary Attacks) auf der Grundlage von Daten, die über einen unsicheren Kanal übermittelt werden, zu ermöglichen.

Im Wesentlichen ist ein einfacher, oder symmetrischer PAKE ein kryptographisches Protokoll, das es zwei Parteien, die nur ein Passwort teilen, ermöglicht, einen starken gemeinsamen geheimen Schlüssel zu erstellen. Die Ziele von PAKE sind:

1) Die geheimen Schlüssel werden übereinstimmen, wenn die Passwörter übereinstimmen, und ansonsten zufällig erscheinen.
2) Die Teilnehmer brauchen Dritten nicht zu vertrauen (insbesondere keiner Public-Key-Infrastruktur),
3) Niemand, der nicht am Protokoll beteiligt ist, erfährt den resultierenden geheimen Schlüssel - auch nicht diejenigen, die das Passwort kennen.
4) Das Protokoll gibt das jeweilige Passwort der beiden Parteien weder untereinander (es sei denn, die Passwörter stimmen überein) noch an Datenspione weiter.

Zusammenfassend lässt sich sagen, dass die einzige Möglichkeit, das Protokoll erfolgreich anzugreifen, darin besteht, das Passwort während der Teilnahme am Protokoll richtig zu erraten. (Glücklicherweise können solche Angriffe meist durch Rate-Limiting vereitelt werden, d.h. durch das Blockieren der Anmeldung eines Benutzers nach einer bestimmten Anzahl falscher Passwortversuche).

Angesichts dieser Anforderungen ist Passwort-via-TLS eindeutig kein PAKE, denn:

  • Es stützt sich auf WebPKI, das Vertrauen in Dritte, so genannte Zertifizierungsstellen (Certificate Authorities), setzt (siehe https://blog.cloudflare.com/introducing-certificate-transparency-and-nimbus/ für eine ausführliche Erklärung von WebPKI und einige seiner Schwachstellen)
  • Das Passwort des Benutzers wird dem Server mitgeteilt.
  • Passwort-via-TLS bietet dem Benutzer nicht die Sicherheit, dass der Server sein Passwort oder eine Abwandlung davon kennt -- ein Server könnte jede Eingabe des Benutzers ohne jegliche Überprüfung akzeptieren.

Trotzdem ist PAKE immer noch schlechter als Passwort-via-TLS, einfach weil der Server Klartext-Passwörter speichern muss. Wenn wir die aktuell im Einsatz befindlichen Praktiken schlagen wollen, dann benötigen wir eine PAKE, der den Server Salted Hashes speichern lässt.

Eine Verbesserung gegenüber dem einfachen PAKE wird als asymmetrischer PAKE (APAKE) bezeichnet, da nur der Client das Passwort kennt und der Server ein gehashtes Passwort kennt. Ein aPAKE hat die vier Eigenschaften von PAKE und noch eine weitere:

5) Ein Angreifer, der auf dem Server gespeicherte Passwortdaten stiehlt, muss einen Wörterbuchangriff durchführen, um das Passwort abzurufen.

Das Problem mit den meisten bestehenden APAKE-Protokollen ist jedoch, dass sie keine Salted Hashes erlauben (oder wenn sie es tun, verlangen sie, dass das Salt an den Benutzer übertragen wird, was bedeutet, dass der Angreifer vorher Zugriff auf das Salt hat und mit der Berechnung einer Regenbogentabelle für den Benutzer beginnen kann, bevor er jegliche Daten stiehlt). Wir möchten die Sicherheitseigenschaft daher wie folgt erweitern:

5*) Ein Angreifer, der Passwortdaten stiehlt, die auf dem Server gespeichert sind, muss einen Wörterbuchangriff pro Benutzer durchführen, um das Passwort nach der Kompromittierung der Daten abzurufen.

OPAQUE ist das erste aPAKE-Protokoll mit einem formalen Sicherheitsnachweis, das diese Eigenschaft hat: Es erlaubt ein völlig geheimes Salt.

OPAQUE - Server schützen Geheimnisse, ohne diese zu kennen!

OPAQUE ist das, was man als starken aPAKE bezeichnet, was einfach bedeutet, dass sich diesen Prä-Computing-Angriffen widersetzt, indem es einen heimlichen Salted-Hash auf dem Server verwendet. OPAQUE wurde 2018 von Stanislaw Jarecki, Hugo Krawcyzk und Jiayu Xu vorgeschlagen und formell analysiert (Hinweis: Stanislaw Jarecki ist mein akademischer Betreuer). Der Name OPAQUE ist eine Kombination aus den Namen zweier kryptographischer Primitive: OPRF und PAKE. PAKE kennen wir bereits, aber was ist eine OPRF? OPRF steht für Oblivious Pseudo-Random Function (Pseudozufallsfunktion), ein Protokoll, mit dem zwei Parteien eine Funktion F(Schlüssel, x) berechnen, die deterministisch ist, aber zufällig aussehende Werte ausgibt. Eine Partei gibt den Wert x ein, und eine andere Partei gibt den Schlüssel ein - die Partei, die x eingibt, erfährt das Ergebnis F (Schlüssel, x)aber nicht den Schlüssel, und die Partei, die den Schlüssel bereitstellt, erfährt nichts.  (Hier finden Sie nähere Informationen über die Mathematik hinter den OPRFs: https://blog.cloudflare.com/privacy-pass-the-math/).

Im Kern ist OPAQUE eine Methode, um Benutzergeheimnisse zur sicheren Aufbewahrung auf einem Server zu speichern, ohne dem Server Zugriff auf diese Geheimnisse zu gewähren. Anstatt einen traditionellen Salted Passwort-Hash zu speichern, speichert der Server für Sie eine geheime Envelope, die durch zwei Informationen „verschlossen“ ist: Ihr Passwort, das nur Ihnen bekannt ist, und einen zufälligen geheimen Schlüssel (wie ein Salt), der nur dem Server bekannt ist. Um sich anzumelden, initiiert der Client einen kryptografischen Austausch, der den Envelope-Schlüssel dem Client, aber - und das ist wichtig - nicht dem Server offenbart.

Der Server sendet dann die Envelope an den Benutzer, der nun die verschlüsselten Schlüssel abrufen kann. (Die in der Envelope enthaltenen Schlüssel sind ein privates-öffentliches Schlüsselpaar für den Benutzer und ein öffentlicher Schlüssel für den Server). Sobald diese Schlüssel entsperrt sind, werden sie die Eingaben für ein Authenticated Key Exchange (AKE)-Protokoll sein, das es dem Benutzer und dem Server ermöglicht, einen geheimen Schlüssel zu erstellen, der zur Verschlüsselung ihrer zukünftigen Kommunikation verwendet werden kann.

OPAQUE besteht aus zwei Phasen, nämlich der Registrierung von Anmeldedaten und der Anmeldung via Schlüsselaustausch.

OPAQUE: Registrierungsphase

Vor der Registrierung meldet sich der Nutzer zunächst für das Service an und wählt einen Benutzernamen und ein Passwort. Die Registrierung beginnt mit dem OPRF-Fluss, den wir gerade beschrieben haben: Alice (der Benutzer) und Bob (der Server) führen einen OPRF-Austausch durch. Das Ergebnis ist, dass Alice einen zufälligen Schlüssel rwd erhält, der aus dem OPRF-Output F(Schlüssel, pwd) abgeleitet wird, wobei Schlüssel ein im Besitz des Server befindlicher, für Alice spezifischer Schlüssel ist und pwd für Alices Passwort steht.

Innerhalb seiner OPRF-Nachricht sendet Bob seinen öffentlichen Schlüssel für seine OPAQUE-Identität. Dann erzeugt Alice ein neues privates/öffentliches Schlüsselpaar, das ihre dauerhafte OPAQUE-Identität für Bobs Dienst sein wird, und verschlüsselt ihren geheimen Schlüssel gemeinsam mit Bobs öffentlichem Schlüssel mit dem rwd (wir werden das Ergebnis als eine verschlüsselte Envelope bezeichnen.) Sie schickt diese verschlüsselte Envelope zusammen mit ihrem öffentlichen Schlüssel (unverschlüsselt) an Bob, der die von ihr bereitgestellten Daten zusammen mit dem Alice-spezifischen OPRF-Geheimnis in einer Datenbank speichert, die nach ihrem Benutzernamen indiziert ist.

OPAQUE: Anmeldephase

Die Anmeldephase ist sehr ähnlich. Es beginnt auf dieselbe Weise wie die Registrierung -- mit einem OPRF-Fluss. Serverseitig generiert Bob jedoch keinen neuen OPRF-Schlüssel, sondern schlägt stattdessen denjenigen nach, den er während der Registrierung von Alice erstellt hat. Er macht dies, indem er Alices Benutzernamen (den sie in der ersten Nachricht angibt) nachschlägt und seinen Datensatz von ihr abruft. Der Datensatz enthält ihren öffentlichen Schlüssel, ihre verschlüsselte Envelope und Bobs OPRF-Schlüssel für Alice.

Er übermittelt auch die verschlüsselte Envelope, die Alice mit der Ausgabe des OPRF-Flusses entschlüsseln kann. (Wenn die Entschlüsselung fehlschlägt, bricht sie das Protokoll ab -- wahrscheinlich ist dies ein Hinweis darauf, dass sie ihr Passwort inkorrekt eingegeben hat oder dass Bob nicht der ist, für den er sich ausgibt.) Wenn die Entschlüsselung gelingt, hat sie nun ihren eigenen geheimen Schlüssel und Bobs öffentlichen Schlüssel. Sie gibt diese mit Bob in ein AKE-Protokoll ein, der im Gegenzug auch seinen privaten Schlüssel und ihren öffentlichen Schlüssel eingibt, wodurch sie beide einen neuen gemeinsamen, geheimen Schlüssel erhalten.

Integrieren von OPAQUE in einen AKE

Eine wichtige Frage an dieser Stelle ist: Welche AKE ist für OPAQUE geeignet? Die entstehende CFRG-Spezifikation skizziert mehrere Optionen, darunter 3DH und SIGMA-I. Im Internet steht uns jedoch bereits ein AKE zur Verfügung: TLS!

Erinnern Sie sich daran, dass TLS ein AKE ist, weil es eine unilaterale (und gegenseitige) Authentifizierung mit gemeinsamer geheimer Ableitung bietet. Der Kern von TLS ist ein Diffie-Hellman-Schlüsselaustausch, der an sich nicht authentifiziert ist. Das bedeutet, dass die Parteien, die ihn durchführen, keine Möglichkeit haben, zu überprüfen, mit wem sie diesen durchführen. (Dies ist ein Problem, denn wenn Sie sich bei Ihrer Bank oder einer anderen Website anmelden, die Ihre privaten Daten speichert, wollen Sie sicher sein, dass sie die sind, für die sie sich ausgeben). Die Authentifizierung verwendet in erster Linie Zertifikate, die von vertrauenswürdigen Entitäten über ein System namens Public Key Infrastructure (PKI). Jedes Zertifikat ist mit einem geheimen Schlüssel verbunden. Um seine Identität nachzuweisen, legt der Server dem Client sein Zertifikat vor und signiert den TLS-Handshake mit seinem geheimen Schlüssel.

Eine Änderung dieser allgegenwärtigen zertifikatsbasierten Authentifizierung im Web ist vielleicht nicht der beste Ausgangspunkt. Eine Verbesserung wäre stattdessen die Authentifizierung des gemeinsamen TLS-Geheimnisses, unter OPAQUE, nachdem der TLS-Handshake abgeschlossen ist. Mit anderen Worten, sobald ein Server mit seinem typischen WebPKI-Zertifikat authentifiziert ist, könnten sich Clients anschließend beim Server authentifizieren. Diese Authentifizierung könnte „nach dem Handshake“ in der TLS-Verbindung mit OPAQUE erfolgen.

Exportierte Authentifikatoren sind ein Mechanismus für eine Authentifizierung in TLS, die „nach dem Handshake“ stattfindet. Sie ermöglichen es einem Server oder Client, den Nachweis einer Identität zu erbringen, ohne eine neue TLS-Verbindung einzurichten. Erinnern Sie sich daran, dass im Standard-Webfall der Server ihre Identität mit einem Zertifikat nachweist (zum Beispiel, dass sie „cloudflare.com“ sind). Wenn derselbe Server jedoch auch alternative Identitäten besitzt, müssen sie TLS erneut ausführen, um zu beweisen, wer sie sind.

Der grundlegende Exportierte Authentifikatoren-Fluss ähnelt einem klassischen Challenge-Response-Protokoll und funktioniert wie folgt: (Wir betrachten nur den Fall der Server-Authentifizierung, da der Client-Fall symmetrisch ist).

Zu jedem Zeitpunkt nach dem Aufbau einer TLS-Verbindung sendet Alice (der Client) eine Authentifizierungsanfrage, um mitzuteilen, dass sie möchte, dass Bob (der Server) eine zusätzliche Identität nachweist. Diese Anfrage umfasst einen Kontext (eine unvorhersehbare Zeichenfolge -- betrachten Sie dies als eine Herausforderung) und Erweiterungen, die Informationen darüber enthalten, welche Identität der Client erhalten möchte. Zum Beispiel könnte der Client die Erweiterung SNI einschließen, um den Server um ein Zertifikat zu bitten, das mit einem bestimmten Domainnamen verbunden ist, der sich von dem ursprünglich in der TLS-Verbindung verwendeten unterscheidet.

Wenn der Server nach Erhalt der Client-Nachricht ein gültiges Zertifikat besitzt, das der Anforderung entspricht, sendet er einen Exportierten Authentifikator zurück, der beweist, dass er den geheimen Schlüssel für das Zertifikat besitzt. (Diese Nachricht hat dasselbe Format wie eine Auth-Nachricht vom Client im TLS 1.3-Handshake - sie enthält ein Zertifikat, ein CertificateVerify und eine „Finished“-Nachricht). Wenn sich der Server nicht mit dem angeforderten Zertifikat authentifizieren kann oder möchte, antwortet er mit einem leeren Authentifikator, der nur eine wohlgeformte „Finished“-Nachricht enthält.

Der Client prüft dann, ob der Exportierte Authentifikator, den er erhält, wohlgeformt ist, und verifiziert dann, ob das vorgelegte Zertifikat gültig ist. Wenn ja, akzeptiert er die neue Identität.

Zusammenfassend lässt sich sagen, dass Exportierte Authentifikatoren eine sichere Authentifizierung auf einer höheren Ebene (z. B. der Anwendungsebene) bieten, indem die bewährte Kryptographie und die Nachrichtenformate von TLS genutzt werden. Außerdem ist sie an die TLS-Sitzung gebunden, so dass Authentifizierungsnachrichten nicht von einer TLS-Verbindung in eine andere kopiert und eingefügt werden können. Mit anderen Worten: Exportierte Authentifikatoren bieten genau die richtigen Hooks, um OPAQUE-basierte Authentifizierung in TLS hinzuzufügen.

OPAQUE mit Exported Authenticators (OPAQUE-EA)

OPAQUE-EA [OPAQUE-EA] ermöglicht die Ausführung von OPAQUE an jedem beliebigen Punkt, nachdem bereits eine TLS-Verbindung eingerichtet wurde. Rufen Sie sich in Erinnerung, dass Bob (der Server) seine OPAQUE-Identität speichert, in diesem Fall einen Signierungs- und Verifizierungsschlüssel, und Alice wird ihre Identität -- verschlüsselt -- auf Bobs Server speichern. (Der Registrierungsfluss, in dem Alice ihre verschlüsselten Schlüssel speichert, ist derselbe wie in regulärem OPAQUE, mit dem Unterschied, dass sie einen Signierschlüssel speichert, so dass wir direkt zur Anmeldung übergehen). Alice und Bob führen zwei Anforderung-Authentifizierung-EA-Flüsse durch (einen für jede Partei); auch OPAQUE-Protokollnachrichten, die sich im Erweiterungsabschnitt der EAs befinden, werden dabei mitübertragen. Sehen wir uns im Detail an, wie das funktioniert.

Zunächst generiert Alice ihre OPRF-Nachricht auf der Grundlage ihres Passworts. Sie erstellt eine Authentifizierungsanfrage, in der sie Bobs OPAQUE-Identität abfragt und (im Feld Erweiterungen) ihren Benutzernamen und ihre OPRF-Nachricht angibt, und sendet diese über ihre bestehende TLS-Verbindung an Bob.

Bob erhält die Nachricht und sucht Alices Benutzernamen in seiner Datenbank. Er ruft seinen OPRF-Schlüssel und ihren OPAQUE-Datensatz ab, wobei letzterer ihren Verifizierungsschlüssel und ihre verschlüsselte Envelope enthält. Er wendet den OPRF-Schlüssel auf die OPRF-Nachricht an und erstellt einen Exportierten Authentifikator, der den Besitz seines OPAQUE-Signierschlüssels beweist, mit einer Erweiterung, die seine OPRF-Nachricht und die verschlüsselte Envelope enthält. Zusätzlich sendet er eine neue Authentifizierungsanfrage, in der er Alice bittet, den Besitz ihres OPAQUE-Signierschlüssels nachzuweisen.

Alice parst die Nachricht und vervollständigt die OPRF-Überprüfung mit Bobs Nachricht, um als Output rwd zu erhalten, und verwendet rwd, um die verschlüsselte Envelope zu entschlüsseln. Dies offenbart ihren Signierschlüssel und Bobs öffentlichen Schlüssel. Sie verwendet Bobs öffentlichen Schlüssel, um seinen Authenticator-Response-Nachweis zu validieren, und wenn der Nachweis stimmt, erstellt und sendet sie einen Exportierten Authentifikator, der beweist, dass sie den neu entschlüsselten Signierschlüssel besitzt. Bob überprüft die Gültigkeit ihres Exportierten Authentifikators, und wenn dieser überprüft wurde, akzeptiert er ihre Anmeldung.

Mein Projekt: OPAQUE-EA über HTTPS

Alles, was oben beschrieben wurde, wird durch eine Unmenge an Theorie unterstützt, die erst noch ihren Weg in die Praxis finden muss. Mein Projekt hatte das Ziel, die Theorie in die Realität umzusetzen. Ich begann mit schriftlichen Beschreibungen von Exportierten Authentifikatoren, OPAQUE und einem Vorentwurf von OPAQUE-in-TLS . Mein Ziel war es, hiervon ausgehend einen funktionierenden Prototyp zu entwickeln.

Meine Demo zeigt die Durchführbarkeit der Implementierung von OPAQUE-EA im Web, wobei Klartext-Passwörter vollständig, auch verschlüsselt, aus der Leitung entfernt werden. Dies bietet eine mögliche Alternative zum derzeitigen Passwort-via-TLS-Fluss mit besseren Sicherheitseigenschaften, aber ohne sichtbare Änderung für den Benutzer.

Einige Details der Implementierung sind wissenswert. Die Abstraktion ist in der Informatik ein mächtiges Werkzeug. Das bedeutet, dass wir uns oft auf bestehende Tools und APIs stützen können, um doppelte Arbeit zu vermeiden. In meinem Projekt habe ich mich stark auf mint gestützt, eine Open-Source-Implementierung von TLS 1.3 in Go, die sich hervorragend für das Prototyping eignet. Ich habe auch die CIRCL-Bibliothek benutzt. Ich habe Programbibliotheken für Exportierte Authentifikatoren, den Kern von OPAQUE, und OPAQUE-EA (das die beiden verbindet) aufgebaut.

Ich habe die Web-Demo erstellt, indem ich die OPAQUE-EA-Funktionalität in einen einfachen HTTP-Server und -Client verpackt habe, die sich gegenseitig Nachrichten über HTTPS übermitteln. Da ein Browser Go nicht ausführen kann, habe ich aus Go nach WebAssembly (WASM) kompiliert, um die Go-Funktionalität im Browser zu erhalten, und ein einfaches Skript in JavaScript geschrieben, um die benötigten WASM-Funktionen aufzurufen.

Da aktuelle Browser keinen Zugriff auf die zugrundeliegende TLS-Verbindung auf der Client-Seite erlauben, musste ich einen Workaround implementieren, um dem Client den Zugriff auf die Exporter Keys zu ermöglichen, nämlich dass der Server die Schlüssel einfach berechnet und über HTTPS an den Client sendet. Dieser Workaround verringert die Sicherheit der daraus resultierenden Demo -- das bedeutet, dass man darauf vertraut, dass der Server die richtigen Schlüssel bereitstellt. Trotzdem ist das Passwort des Benutzers immer noch sicher, selbst wenn ein böswilliger Server schlechte Schlüssel zur Verfügung gestellt hat -- er hat nur keine Gewissheit, dass er sich tatsächlich vorher bei diesem Server registriert hat. In Zukunft könnten die Browser jedoch einen Mechanismus zur Unterstützung exportierter Schlüssel umfassen und OPAQUE-EA mit seinen vollen Sicherheitseigenschaften laufen lassen.

Sie können meine Implementierung auf Github erkunden und sogar den Anweisungen folgen, um Ihren eigenen OPAQUE-EA-Testserver und -Client hochzufahren. Ich möchte jedoch betonen, dass die Implementierung nur als Proof-of-Concept gedacht ist und für Produktionssysteme nicht ohne wesentliche weitere Überprüfung verwendet werden darf.

Limitationen von OPAQUE-EA

Trotz seiner großartigen Eigenschaften gibt es definitiv einige Hürden, die man überwinden muss, um OPAQUE-EA von einem Proof-of-Concept zu einem vollwertigen Authentifizierungsmechanismus zu machen.

Browser-Unterstützung für TLS-Exporter-Keys. Wie bereits kurz erwähnt, müssen Sie, um OPAQUE-EA in einem Browser auszuführen, auf Geheimnisse der TLS-Verbindung zugreifen, welche als Exporter Keys bezeichnet werden. In den derzeit gängigsten Browsern ist dies nicht möglich, so dass eine Unterstützung für diese Funktionalität hinzugefügt werden muss.

Überarbeitung von Passwort-Datenbanken. Um OPAQUE-EA zu implementieren, müssen Server nicht nur ihre Passwort-Prüflogik aktualisieren, sondern auch ihre Passwort-Datenbanken komplett überarbeiten. Da OPAQUE auf spezielle Passwort-Darstellungen angewiesen ist, die nur interaktiv generiert werden können, können bestehende Salted-Hash-Passwörter nicht automatisch in OPAQUE-Datensätze umgewandelt werden. Server werden wahrscheinlich einen speziellen OPAQUE-Registrierungsfluss per einzelnem Nutzer ausführen müssen. Da OPAQUE sowohl vom Client als auch vom Server befürwortet werden muss, müssen Server möglicherweise noch für längere Zeit die alte Methode unterstützen, bevor alle Clients aufholen.

Abhängigkeit von neu entstehenden Standards. OPAQUE-EA stützt sich auf OPRFs, die sich im Prozess der Standardisierung befinden, und auf Exportierte Authentifikatoren, einen vorgeschlagenen Standard. Das bedeutet, dass die meisten bestehenden kryptographischen Bibliotheken noch keine Unterstützung für diese Abhängigkeiten bieten, sodass Early Adopter diese Werkzeuge möglicherweise selbst implementieren müssen.

Zusammenfassung

Solange Menschen noch Passwörter verwenden, möchten wir den Prozess so sicher wie möglich gestalten. Die derzeitigen Methoden beruhen auf der riskanten Praxis, Klartext-Passwörter serverseitig zu verarbeiten und ihre Richtigkeit zu überprüfen. PAKEs und (insbesondere aPAKEs) erlauben eine sichere Anmeldung mit Passwörtern, ohne dass der Server die Passwörter jemals sehen kann. OPAQUE ist eine der besten aPAKEs auf dem Markt und kann vollständig in TLS integriert werden. Sie können den Code hier ausprobieren.

[1] Bellovin, S. M., and Merritt, M. “Encrypted key exchange: Password-based protocols secure against dictionary attacks.” Proc. IEEE Computer Society Symposium on Research in Security and Privacy (Oakland, May 1992), 72–84.