HTML5-Offline-Authentifizierung

8

Ich suche Rat / Kritik darüber, wie der Zugriff auf eine HTML5-Anwendung, die überwiegend offline verwendet wird, am besten kontrolliert werden kann.

Die Anwendung verwendet eine Kombination aus IndexedDB, lokalem Speicher und Sitzungsspeicher zum Speichern von Daten, sodass sie offline verwendet werden kann. Die Daten / Seiten werden über HTTPS bedient.

Das Ziel besteht darin, das Risiko zu minimieren, dass die Daten angezeigt werden, wenn das Tablet / der PC verloren gegangen ist oder gestohlen wurde.

Derzeit verwendet die Anwendung die Stanford JavaScript Crypto-Bibliothek, um den Benutzer / das Kennwort zu verschlüsseln und sie dann auf dem lokalen Speicher zu speichern, wenn der Benutzer sich erfolgreich am Server authentifizieren kann. Wenn die Anwendung dann offline geht, muss ein Benutzer "lokal" gegen den verschlüsselten Benutzer / das Kennwort im lokalen Speicher authentifizieren.

Zusätzlich wird ein unverschlüsselter Benutzer / Passwort im Sitzungsspeicher gespeichert, wenn der Benutzer sich erfolgreich am Server authentifizieren kann. Dies wird verwendet, damit die Anwendung in regelmäßigen Abständen versuchen kann, den Kontakt mit dem Server wiederherzustellen und sich "erneut" zu authentifizieren, ohne dass der Benutzer seine Anmeldeinformationen erneut eingeben muss.

Ich bin mir einer Reihe von Posts / Diskussionen über die Fehlbarkeit der clientseitigen Verschlüsselung bewusst, siehe Ссылка und Ссылка und .nczonline.net / blog / 2010/04 / 13 / Richtung-mehr-Secure-Client-Side-Data-Storage / + andere. Ich bin jedoch unsicher, wie diese Argumente in diesem Szenario gelten.

Ich suche Kritik an dem Ansatz, da Daten offline gespeichert werden müssen. Wenn es einen besseren Ansatz gibt, bitte erläutern.

Danke

    
user3566458 23.04.2014, 22:28
quelle

2 Antworten

2

Authentifizierung vs. sicherer Speicher

Ich fange mit dem großen Designproblem an: Sie scheinen mit dem Problem zu arbeiten, als ob es um Authentifizierung geht, wo der (potentiell bösartige) Benutzer Ihrer Bewerbung beweisen muss, dass sie es wirklich ist ist ein gültiger Benutzer. Sie stehen jedoch vor einem Speicherproblem , da die gesamte Laufzeitumgebung, in der alle sensiblen Informationen enthalten sind, mit denen Ihre Anwendung arbeitet, in der Hand des Angreifers liegt, wenn das Computergerät gestohlen wird. Im Falle einer Javascript-Anwendung ist die Analyse der Offline-Daten und des Codes sogar noch komfortabler als bei einigen Binärcodes.

Wenn ich zum Beispiel Ihre Anwendung angreifen würde, würde ich zuerst in den Sitzungsspeicher schauen (Cookies? Verwenden Sie einfach die Browser-Schnittstelle, um sie nachzuschlagen) und sehen, ob ich dort den Benutzernamen und das Passwort finden kann. Wenn nicht, würde ich dem Code folgen, der verwendet wird, um das Kennwort in dem lokalen Speicher zu entschlüsseln (wahrscheinlich mit einem Javascript-Debugger). Wie Sie Ihre Anwendung beschrieben haben, scheint es so, als könnten die Funktionen sie ohne einen vom Benutzer bereitgestellten Schlüssel entschlüsseln. Vielleicht kann ich die lokale Authentifizierung des Benutzers einfach auskommentieren, indem ich etwas wie if(authenticateUser()) in if(true) ändere.

Sie müssen also wirklich alle sensiblen lokalen Daten mit einem Schlüssel verschlüsseln, der überhaupt nicht auf der Client-Seite gespeichert ist. Fragen Sie zum Beispiel den Benutzer bei jedem Zugriff auf Ihre Anwendung nach einem Entschlüsselungsschlüssel, verwenden Sie diesen Schlüssel zum Entschlüsseln der lokal gespeicherten Daten (und verschlüsseln Sie alle neuen Daten, die Sie speichern) und nach einer bestimmten Zeit der Inaktivität den Schlüssel wegwerfen . Oder Sie können den Benutzer bei jedem Zugriff auf die Anwendung gegen den Server authentifizieren und den Entschlüsselungsschlüssel von dort abrufen und nach einer bestimmten Inaktivitätszeit wegwerfen.

An dieser Stelle behindert die Wahl einer JavaScript-Umgebung wirklich Ihre Ursache, da Sie die Laufzeitumgebung nicht dazu zwingen können, den Entschlüsselungsschlüssel wegzuwerfen, wenn Sie ihn weg haben wollen. Es ist schwierig genug mit C-Anwendungen sogar, da Sie sorgfältig das RAM auf der Festplatte auslagern müssen. Abhängig davon, wie vertraulich die Informationen sind, mit denen Ihre Anwendung arbeitet, reicht es aus, den Benutzer nach Beendigung des Browsers zu bitten, den Browser zu schließen und davon auszugehen, dass ein Angreifer nicht genügend motiviert ist, im ausgelagerten RAM des Browsers nach dem Schlüssel zu suchen / p>

Lokale Speicherung der Anmeldedaten

Da es sich um die vertraulichsten Informationen handelt, mit denen Sie arbeiten, sollten Sie die Anmeldeinformationen des Benutzers niemals auf dem Client speichern. Stattdessen authentifizieren Sie sich einmal gegenüber dem Server und rufen ein Authentifizierungstoken für zukünftige Interaktionen ab. Dies wäre im Grunde identisch mit einem Session-Cookie und läuft nach einiger Zeit ab (wenn es nicht abläuft, ist es so gut wie das Passwort).

    
Perseids 24.04.2014 08:05
quelle
1

Ich habe jetzt eine Lösung implementiert, die ich unten beschreibe, falls sie für jemand anderen nützlich ist. Ich verstehe, es ist "keine Antwort" auf meine Frage, dh bietet keine Kritik, aber angesichts der Tatsache, dass die Anwendung "offline" zusammen mit der Anforderung der nahtlosen Re-Authentifizierung funktionieren muss, kann ich nicht sehen, wie @Perseids Antwort kann implementiert werden, obwohl Ich schätze den Dialog (sowohl von @SilverlightFox als auch von @Perseids).

Wenn es eine Lösung gibt, die Anmeldeinformationen des Benutzers nicht offline zu speichern, während die Anforderungen erfüllt sind, die in meiner Frage beschrieben sind, würde ich gerne hören.

Die Anwendung muss in der Lage sein, einen Benutzer zu authentifizieren, wenn die Anwendung "online" und "offline" ist. Für eine "Online" -Anwendung würde normalerweise eine Sitzungstokenlösung angenommen werden, d. H. Nur eine Sitzungskennung würde auf dem Client (normalerweise in einem Cookie) gespeichert werden, aber nicht die Anmeldeinformationen des Benutzers. Die Anmeldeinformationen des Benutzers müssen jedoch unbedingt auf dem Client gespeichert werden (vielleicht wird jemand eine clevere Alternative finden?), So dass die Sicherheit erzwungen werden kann, während die Anwendung offline ist, d. H. Einem Benutzer erlauben, sich offline zu authentifizieren und IndexedDB-Daten zu entschlüsseln / verschlüsseln. Um die Anwendung sicherer zu machen, werden Benutzername und Passwort des Benutzers in verschlüsselter Form gespeichert. Einige sensible IndexedDB-Daten werden ebenfalls in verschlüsselter Form gespeichert. Selbst wenn ein böswilliger Benutzer den Computer oder das Tablet mit einer zwischengespeicherten Instanz der Anwendung erhalten würde, könnten sie nur die Benutzernamen, Kennwörter und Daten in ihrer verschlüsselten Form anzeigen (vorausgesetzt, der Benutzer hat sich abgemeldet oder seinen Browser geschlossen).

Leider scheint es zu dieser Zeit kein "Standard" -Protokoll für die Sicherung von HTML5-Offline-Anwendungen zu geben. Fast die gesamte Literatur warnt davor, Benutzerdaten oder sensible Daten auf dem Client zu speichern. Dies ist jedoch ein Paradoxon, da diese Anwendung offline arbeiten muss, daher müssen die Daten offline gespeichert werden.

Das Sicherheitsprotokoll, das hier implementiert wird, hat zwei Schlüssel, obwohl, sobald der erste Schlüssel geknackt ist, es leicht ist, den zweiten Schlüssel zu erhalten. In der ersten Ebene wird das Passwort des Benutzers mit seinem eigenen Passwort verschlüsselt, zusammen mit dem Benutzernamen als Salz. Es gibt auch einen zweiten Schlüssel, den "Datenverschlüsselungsschlüssel", der nach erfolgreicher Authentifizierung beim Server vom Server zurückgegeben wird. Dieser Schlüssel wird verwendet, um sowohl den Benutzernamen als auch alle IndexedDB-Daten zu verschlüsseln. Dieser "Datenverschlüsselungsschlüssel" wird mit dem Benutzerpasswort erneut verschlüsselt. Wenn also ein Angreifer in der Lage sein würde, das Passwort des Benutzers zu entschlüsseln, könnte er das Passwort einfach dazu verwenden, den "Datenverschlüsselungsschlüssel" zu entschlüsseln und anschließend den Benutzernamen und verschlüsselte IndexedDB-Daten zu entschlüsseln . Nur die verschlüsselte Form der Benutzernamen, Passwörter und Daten muss dann dauerhaft auf dem Client gespeichert werden, da es dann möglich ist, durch die Verwendung des Benutzernamens und des Passworts, die in den Login-Bildschirm eingegeben wurden, alle persistenten Daten zu entschlüsseln.

Nach der Anmeldung werden Benutzername und Passwort jedoch unverschlüsselt in der Clientsitzung gespeichert, sodass 1) die Anwendung sich regelmäßig erneut mit dem Server authentifizieren kann. Dies macht die Neuauthentifizierung bei intermittierender Konnektivität nahtlos 2) den entschlüsselten Datenverschlüsselungsschlüssel jederzeit abrufen, um die IndexedDB-Daten abfragen / speichern zu können und sie bei Bedarf entschlüsseln / verschlüsseln zu können. Wenn 1) keine Anforderung wäre, sollte nur der Datenverschlüsselungsschlüssel in der Sitzung gespeichert werden. Dies führt zu einer Gefährdung, wenn der Benutzer sich nicht abgemeldet hat oder seinen Browser nicht geschlossen hat, da ein böswilliger Benutzer dann das Passwort und den Benutzernamen des Benutzers in seiner entschlüsselten Form (mit einem Debugging-Tool) sehen könnte. Dies ist jedoch nicht viel schlimmer als das Gleiche wie bei einer herkömmlichen Online-Anwendung, die dem Benutzer die Möglichkeit gibt, sein Passwort zu ändern, obwohl eine traditionelle Online-Anwendung normalerweise ein Sitzungszeitlimit hat, so dass der böswillige Benutzer nur eine begrenzte Zeit zum Handeln hat. Auch wenn der Browser abstürzt, gibt es normalerweise dem Benutzer die Möglichkeit, seine vorherigen Fenster / Tabs mit ihren Sitzungsinformationen wiederherzustellen, daher sollte der Browser ordnungsgemäß geschlossen werden.

Das oben genannte Protokoll folgt fast sicher nicht den besten Praktiken. Zum Beispiel das Salz ist nicht zufällig (Benutzername umgekehrt), ist wahrscheinlich kurz, vunerable zu einem Wörterbuch Angriff, das gleiche kann für das Passwort gelten (die Stärke des Passworts ist eine Funktion des Servers), gibt es keine Key-Stretching z.B PBKDF2. Ich kann jedoch nicht erkennen, wie es möglich ist, "Best Practices" zu befolgen und die Anforderungen in Bezug auf die auferlegten Beschränkungen zu erfüllen. Es kann möglich sein, das Hashing ein wenig zu verbessern, z.Verbessere das Salz, vielleicht eine Kombination aus dem Benutzernamen und einer site-spezifischen Zeichenfolge, aber selbst das würde Logik im Javascript erfordern, die von einem entschlossenen Angreifer verstanden werden könnte. Das Javascript kann verschleiert werden, aber auch das macht es nur schwieriger, aber nicht unmöglich und jede Person, die in der Lage ist, die Verschlüsselungsschlüssel zu knacken, würde die Verschleierung des Javascript kaum als Hindernis empfinden. Vielleicht wird mit einer zukünftigen cleveren inhärenten integrierten Unterstützung durch den Browser eine signifikante Verbesserung möglich sein.

    
user3566458 29.05.2014 21:04
quelle