Wie können Sie die Daten serverseitig verschlüsseln, ohne die Benutzererfahrung zu beeinträchtigen?

10

Viele Benutzer - ich selbst eingeschlossen - hätten gerne die Sicherheit, dass alles, was sie an einem Web-Service tun, verschlüsselt wird. Das heißt, sie werden niemanden im Web-Service sehen können: Posts, Infos, Aufgaben, etc ...

Dies ist auch eine große Beschwerde in dieser Diskussion über einen ansonsten coolen Service: Ссылка

Da diese Daten wiederherstellbar sein müssen, ist eine Art Zwei-Wege-Verschlüsselung erforderlich. Aber solange Sie den Benutzer nicht bei jeder Anfrage zur Eingabe des Verschlüsselungsschlüssels auffordern, muss dieser Schlüssel auf dem Server gespeichert werden, und der Punkt der Verschlüsselung der Daten geht im Grunde verloren.

Was ist eine Möglichkeit, Benutzerdaten sicher zu verschlüsseln, ohne die Benutzerfreundlichkeit zu beeinträchtigen (bei jeder Anfrage nach einem Schlüssel fragen)?

- UPDATE -

Von @ Borealids Antwort habe ich mich auf zwei Möglichkeiten konzentriert: Challenge-Response-Protokolle, bei denen keine Daten (einschließlich Passwort) in den "clear" - und non-challenge-response-Protokollen gesendet werden, wo Daten enthalten sind (einschließlich Passwort) wird im "clear" gesendet (obwohl über HTTPS).

Challenge-Response-Protokolle (speziell SRP: Ссылка )

Es sieht so aus, als ob die Implementierung entweder auf einer vollständigen AJAX-Site oder auf einem Webspeicher basieren müsste. Dies ist so, dass der Browser die Abfrage-Antwort-Daten während der Verschlüsselung und auch den Verschlüsselungsschlüssel zwischen verschiedenen "Seiten" persistieren kann. (Ich nehme an, dass nach der Authentifizierung ich den verschlüsselten Verschlüsselungsschlüssel zurücksende, den sie clientseitig entschlüsseln würden, um den echten Verschlüsselungsschlüssel zu erhalten.)

Das Problem ist, dass ich entweder:

bin
  • vollständig AJAX, die ich nicht mag, weil ich URLs liebe und nicht ein Benutzer ausschließlich auf einer einzigen URL leben, oder
  • Ich muss Datenverschlüsselungsschlüssel im Webspeicher speichern, die basierend auf Ссылка auch nach dem Browser bestehen bleiben geschlossen und könnte eine Sicherheitslücke sein

Da SRP mehr als eine Anfrage benötigt ( Ссылка ), muss außerdem eine gewisse Persistenz auf dem Server bestehen -Seite. Dies ist nur eine weitere Schwierigkeit.

Traditionell

Wenn ich Passwörter und Daten im Klartext übermitteln kann (obwohl über HTTPS), dann sind die oben genannten clientseitigen Probleme nicht vorhanden.

Bei der Registrierung erzeuge ich einen zufälligen eindeutigen Verschlüsselungsschlüssel für den Benutzer und verschlüssle ihn mit seinem Passwort und einem zufälligen Salt.

In der Datenbank werde ich den Passwort-Hash und den Salzcode des Benutzers (über bcrypt), den verschlüsselten Verschlüsselungsschlüssel, den Verschlüsselungsschlüssel salt und die Verschlüsselung iv speichern.

Nach einer Authentifizierung muss ich auch ihr Passwort verwenden, um den Verschlüsselungsschlüssel zu entschlüsseln, damit er neue Daten anzeigen und eingeben kann. Ich speichere diesen Verschlüsselungsschlüssel nur vorübergehend und lösche ihn, wenn er sich explizit abmeldet.

Die Probleme mit diesem Ansatz bestehen darin, dass böse Systemadministratoren (wie @Borealid darauf hinweist) immer noch Ihre Daten einsehen können, wenn Sie eingeloggt sind.

Ich bin mir auch nicht sicher, wie die Verschlüsselungsschlüssel gespeichert werden, wenn Benutzer angemeldet sind. Wenn sie sich im selben Datenspeicher befinden, würde eine gestohlene Datenbank alle Daten derjenigen anzeigen, die zum Zeitpunkt des Diebstahls eingeloggt waren / p>

Gibt es einen besseren speicherinternen Datenspeicher zum Speichern dieser Verschlüsselungsschlüssel (und Abfrage von Daten während einer SRP-Authentifizierung)? Ist das etwas, für das Redis gut wäre?

    
ballgame 26.07.2010, 23:53
quelle

4 Antworten

2

Wenn die Daten im Falle eines Benutzerfehlers wiederhergestellt werden müssen, können Sie etwas wie einen Cookie nicht verwenden (der gelöscht werden könnte). Und wie Sie feststellen, sichern serverseitige Schlüssel den Benutzer nicht gegen bösartige Systemadministratoren. Sie helfen nur bei offline gestohlenen Datenbanken.

Wenn Sie jedoch einen normalen Webservice betreiben, haben Sie schon ziemlich viel Glück gehabt - der Benutzer muss angemeldet sein , um einzigartig und nicht ephemer zu sein. Das bedeutet, dass sie einen Authentifizierungsschritt durchlaufen, der ihre Identität beweist. Um ihre Identität zu beweisen, verwenden die meisten Websites einen bestandenen Berechtigungsnachweis (ein Passwort).

Solange Sie kein Challenge-Response-Authentifizierungsprotokoll verwenden, was bei den meisten Websites nicht möglich ist, können Sie einen Verschlüsselungsschlüssel verwenden, der aus einer Kombination aus einem serverseitigen Schlüssel und dem Kennwort des Benutzers abgeleitet wird. Speichern Sie den Verschlüsselungsschlüssel nur, während der Benutzer authentifiziert ist.

Wenn Sie dies tun, sind die Benutzer immer noch anfällig für spähende Systemadministratoren, während sie den Dienst verwenden (oder ihre Kennwörter stehlen). Vielleicht möchten Sie einen Schritt weiter gehen. Um eins hochzugehen, senden Sie das Passwort nicht an den Server. Verwenden Sie stattdessen ein Challenge-Response-Protokoll für die Authentifizierung auf Ihrer Website und verschlüsseln Sie die Daten mit einer Ableitung des Benutzerkennworts über JavaScript, bevor Sie etwas hochladen.

Das ist narrensichere Sicherheit: Wenn Sie versuchen, das Passwort des Benutzers zu stehlen, kann der Benutzer sehen, was Sie tun, weil der Code für den Diebstahl genau dort auf der Seite ist, die Sie ihm geschickt haben. Ihr Webdienst nie berührt seine Daten unverschlüsselt. Dies ist auch kein Hindernis für die normale Benutzererfahrung. Der Benutzer gibt sein Passwort wie üblich zur Anmeldung ein.

Diese Methode wird von Lacies Storage Cloud Service verwendet. Es ist sehr gut gemacht.

Hinweis: Wenn ich sage "benutze foo zum Verschlüsseln", meine ich wirklich "benutze foo, um einen sicheren symmetrischen Schlüssel zu verschlüsseln, der dann mit einem zufälligen Salz zum Verschlüsseln verwendet wird". Kenne deine Kryptographie. Ich rede nur über das Geheimnis, nicht über die Methodik.

    
Borealid 27.07.2010 00:15
quelle
1

Wenn Sie Berechnungen auf einem Server durchführen möchten, ohne dass der Server selbst die Daten sehen kann, sind Sie möglicherweise an einer vollständig homomorphe Verschlüsselung . Mit einem vollständig homomorphen Verschlüsselungsschema können Sie beliebige Berechnungen mit verschlüsselten Daten durchführen, auch wenn Sie sie nicht entschlüsseln können. Dies ist jedoch immer noch ein Forschungsthema.

Für den Moment wäre es am besten, alle Posts zu verschlüsseln und jedem eine sinnlose (z. B. sequenzielle) ID zuzuordnen. Für eine ausführlichere Diskussion darüber, wie serverseitige Daten mit der heutigen Technologie zu verschlüsseln sind, schauen Sie nach.

    
Joey Adams 27.07.2010 00:28
quelle
1

Keine dieser anderen Lösungen wird das angeforderte Feature-Set beibehalten - das speziell die Benutzererfahrung erhalten möchte. Wenn Sie sich die Website ansehen, auf die im Link verwiesen wird, senden Sie eine E-Mail an einen nächtlichen vergangenen Journaleintrag. Sie werden das nicht mit JavaScript-Tricks wie oben beschrieben bekommen, weil Sie nicht auf den Browser angewiesen sind. Das führt Sie also im Grunde zu einem verschlechterten Benutzererlebnis.

Was Sie wollen, oder genauer gesagt, die beste Lösung, die Sie in diesem Raum finden werden, ist nicht so sehr das, was wuala oben tut, sondern eher etwas wie hush.com. Der Umgang mit Benutzerdaten muss immer auf der Client-Seite erfolgen - dies wird in der Regel über volles clientseitiges Java (wie der Facebook-Foto-Uploader etc.) erreicht, aber HTML / JavaScript bringt Sie in diesen Tagen vielleicht hin. Die JavaScript-Verschlüsselung ist ziemlich dürftig, daher solltest du sie besser ignorieren.

OK, Sie haben also auf der Clientseite Java einen Verschlüsselungsdienst für Journaleinträge ausgeführt. Die nächste Funktion bestand darin, jede Nacht Tagebucheinträge an Benutzer per E-Mail zu senden. Nun, Sie werden das offensichtlich nicht in einer unverschlüsselten E-Mail bekommen. Dies ist, wo Sie die Benutzererfahrung auf die eine oder andere Weise ändern müssen. Die einfachste Lösung besteht nicht darin, den Eintrag per E-Mail zu versenden, sondern stattdessen einen Journaleintrags-Browser in der Java-App bereitzustellen, der sie an einen alten Eintrag erinnert, sobald sie über einen Link in der täglichen E-Mail auf die Website gelangt sind. Eine viel komplexere Lösung wäre die Verwendung von JavaScript-Verschlüsselung, um den Eintrag als Anhang in der E-Mail zu entschlüsseln. Dies ist kein Hexenwerk, aber es gibt eine ziemlich große Menge an Tricks. Dies ist der allgemeine Pfad, der von mehreren Web-E-Mail-Verschlüsselungsdiensten wie IronPort verwendet wird. Sie können eine Demo-E-Mail erhalten, indem Sie zu Ссылка gehen.

So gerne ich eine richtig verschlüsselte Version von all dem sehen würde, wäre mein letzter Kommentar, dass Journaleinträge keine Staatsgeheimnisse sind. Angesichts einer soliden Datenschutzerklärung und einer guten Seitensicherheitssemantik bin ich mir sicher, 99% Ihrer Nutzer werden sich mit den Dingen wohl fühlen. All dies mit echter Sicherheit zu tun, wird einen enormen Aufwand pro oben und zumindest einige Design / UE-Änderungen erfordern.

    
cyphers 30.07.2010 16:34
quelle
1

Sie sollten in das MIT-Projekt CryptDB schauen, das die Abfrage einer verschlüsselten Datenbank mit einer Teilmenge von SQL unterstützt. (Siehe verbietet Artikel , mefi thread oder Homomorphe Verschlüsselung auf Wikipedia)

Es gibt auch das Projekt Tahoe-LAFS für Cloud-Speicher, das möglicherweise in einem völlig anonymen Zustand genutzt werden könnte Social-Networking-Anwendung, einen Tag in der fernen Zukunft.

    
Jeff Burdges 21.12.2011 01:40
quelle