Ich habe eine Anwendung entwickelt, die viele Benutzer unterstützt. Die Sache ist, ich kann nicht herausfinden, wie man den Klienten / den Benutzer authentifiziert.
Ich erstelle eine App wie http://quickblox.com/, in der ich meinen Benutzern Anmeldeinformationen gebe und sie verwenden diese, um N Anwendungen zu erstellen, in denen sie ihren Benutzernamen und ihr Kennwort nicht eingeben können, um sich zu authentifizieren.
Nehmen wir an, es geht wie folgt. (Genau wie QuickBlox)
1. Der Benutzer erstellt ein Konto auf meiner Website.
2. Der Benutzer kann N API-Schlüssel erstellen und Anmeldeinformationen absichern. (Für mehrere Apps)
3. Der Benutzer verwendet diese Anmeldeinformationen in seinen Anwendungen (Android, iOS, Javascript usw.), um mit meinen REST-APIs zu kommunizieren.
(REST-APIs haben Lese- und Schreibzugriff.)
Mein Konzern?
Benutzer geben ihre Anmeldeinformationen (API-Schlüssel und geheimer Schlüssel) in Anwendungen ein, die sie erstellen. Was passiert, wenn jemand diese Schlüssel erhält und versucht, den Benutzer zu imitieren? (Durch Dekompilieren von APK oder direktes Betrachten von JavaScript-Code.
Irre ich mich irgendwo?
Ich bin verwirrt, diesen dreistufigen Benutzermechanismus zu entwickeln.
Antworten:
Ich habe in den letzten Jahren REST-APIs entwickelt. Du machst dir zu viele Sorgen. Kürzlich hat ein anderer Benutzer in diesem Forum eine Frage gestellt, wo er sich Sorgen über das Speichern von URI-Endpunkten in seinem clientseitigen JavaScript-Code gemacht hat .
Für Sie gelten die gleichen Regeln wie für den JavaScript-Entwickler. Wenn Sie zulassen, dass Dritte Ihre API integrieren, hat Ihre API dieselbe Sichtbarkeit wie eine normale Website und Sie sollten sie auf dieselbe Weise behandeln.
Zitat aus der ursprünglichen Antwort:
Sie sollten Ihre Anwendungszugriffstoken so gestalten, dass nur Vorgänge zugelassen werden, die Sie zulassen möchten. Sie können zwei Arten von Zugriffstoken haben:
Aber was dekonstruiert jemand den Quellcode, nimmt die Token aus der Anwendung heraus, findet heraus, was die öffentlichen Endpunkte sind und missbraucht Ihren Webdienst?
Wenn Sie die Entwicklung der Anwendungen, die Ihre API verwenden, nicht direkt verwalten, ist es nicht wirklich verboten, dass Benutzer Ihre API auf dieselbe Weise direkt aus der App heraus missbrauchen.
quelle
filtered data
(B) seines Benutzers abzurufen. Jetzt ist es möglich, oder gibt es eine Abhilfe zu verhindern dritte Benutzer alle Daten (A + B) zu stehlen meinen Benutzers . Macht das Sinn?Ihr Problem ist weniger ein technisches als ein geschäftliches.
Nehmen wir an, Sie haben Ihre API, die Sie Ihren Kunden (den App-Entwicklern) zum Pauschalpreis von 100 GBP pro Jahr verkaufen. Unbegrenzter Zugriff.
Dann kann ich natürlich Ihren Service für 100 GBP kaufen und ihn für jeweils 50 USD an 10 Personen verkaufen. Das willst du nicht! Sie versuchen also, sich eine Einschränkung auszudenken, mit der Sie Ihre API verkaufen können, ohne dass Arbitrage möglich ist.
Wenn Sie nur die Anzahl der Apps beschränken, kann ein Kunde eine einzelne App erstellen, die Verbindungen von anderen Apps akzeptiert und weiterleitet.
Wenn Sie die Benutzer einschränken, kann der Kunde Benutzer hinter seiner eigenen Authentifizierung verstecken und als einzelner Benutzer erscheinen.
Sie müssen lediglich die Kosten für jeden API-Aufruf an Ihren Kunden weitergeben. dh Gebühr pro API-Aufruf oder Festlegen einer Quote für Aufrufe pro Jahr.
Dies bringt das gleiche Problem der Arbitrage auf Ihre Kunden. Es zwingt sie, Maßnahmen zu ergreifen, um zu verhindern, dass ihre Benutzer ihre Schlüssel stehlen. In diesem Fall verstecken Sie Ihre API hinter ihrer eigenen, vom Benutzer authentifizierten API.
quelle
Die anderen Antworten scheinen darauf hinzudeuten, dass das Problem der Speicherung eines Geheimnisses in einer App auf Endgeräten nicht lösbar ist.
Sicher ist es das.
Zwei Prinzipien (die Implementierungsdetails werden folgen):
Wenn der Client eine Anforderung mit Anmeldeinformationen an den Authentifizierungsendpunkt sendet und dieser vom Server authentifiziert wird, kann der Server ein dynamisches temporäres Token (temporär, dh zeitbasiert) generieren . Dieses Token sollte im Client gespeichert und mit nachfolgenden Anforderungen gesendet werden.
Sie benötigen einen Mechanismus, um das Token regelmäßig zu "aktualisieren", dh ein neues zu erhalten. Erstellen Sie einfach einen REST-Endpunkt, mit dem Sie aus einem vorhandenen Token ein neues Token generieren können, damit Sie sich nicht erneut anhand der Anmeldeinformationen authentifizieren müssen.
Wenn Sie verhindern möchten, dass sich der Endbenutzer erneut authentifiziert, kann diese Authentifizierung bei der Installation eine einmalige Einrichtung in der App sein.
Diese Lösung vermeidet einfach die Notwendigkeit, ein statisches Token zu speichern, das in der Anwendungsbinärdatei eingebettet ist. Ein Token wird vom Server im laufenden Betrieb nur als Antwort auf eine erfolgreiche Authentifizierung generiert. Damit ein böswilliger Benutzer Ihre Anwendung untersuchen und versuchen kann, nicht autorisierten API-Zugriff zu erhalten, muss er sich wie jeder andere auch authentifizieren.
quelle
Wenn Sie eindeutige app-bezogene Schlüssel haben, können Sie diese nur während einer vom Client initiierten anfänglichen Verbindungsauthentifizierung verwenden. Anschließend wechseln Sie zu einem fortlaufenden, app-bezogenen eindeutigen Authentifizierungstoken.
Ihr Server ändert (rollt) das Token für jede Client-App von Zeit zu Zeit (z. B. in regelmäßigen Abständen plus / minus einer zufälligen Fuzzy- / Zufallsverzögerung). Das Rolling Token ist nur zwischen dem Server und dem authentifizierten Client bekannt.
Die neuen Token werden bei den regulären Antworten huckepack zurückgegeben. Immer wenn die Antwort ein neues Token enthält, muss die empfangende App darauf umstellen, es in nachfolgenden Anforderungen zu verwenden.
Wenn der Austausch mit einem Client nicht mehr synchron ist (irgendein Protokollfehler), fordert Ihr Server eine erneute Authentifizierung an (durch eine Fehlerantwort auf die nächste Clientanforderung oder auf die gültige Antwort auf die Clientanforderung gepackt, z Beispiel).
Die anfängliche Authentifizierung, die von Clients initiiert wird, während ein rollendes Token aktiv verwendet wird, sollte mit Argwohn betrachtet werden - es könnte sich durchaus um einen Nachahmungsversuch handeln. Ich würde es nur zulassen, wenn der Austausch für ein länger als erwartetes Intervall inaktiv ist, was zum Beispiel durch einen Clientausfall / -neustart mit einer neuen Instanz ohne Rolling Token verursacht werden könnte.
Es ist sogar noch besser, das Token auf der Clientseite beizubehalten, sodass ein neu gestarteter Client an der Stelle weitermachen kann, an der sein Vorgänger noch übrig ist, was die Öffnung für die Nachahmung erheblich einschränkt.
Ein solches Schema würde die Nachahmung zumindest ziemlich schwierig machen - der nachahmende Client müsste genau das Fenster vorhersagen, in dem der autorisierte Client keine Anfragen mehr sendet, damit der Server entscheiden kann, ob es in Ordnung ist, eine neue Clientauthentifizierung mit dem vorgeschriebenen Schlüssel zu akzeptieren. Solche Anfragen außerhalb des erlaubten Fensters können als Erkennung von Nachahmungsversuchen verwendet werden und möglicherweise Gegenmaßnahmen einleiten (IP-Blacklisting usw.).
quelle
Soweit ich weiß, ist das, was Sie erwähnt haben, der einzige Weg, dies zu tun. Die Anwendung, die den Schlüssel speichert, ist definitiv ein Risiko, aber es gibt verschiedene Möglichkeiten, ihn zu umgehen. Sie können den Schlüsselspeicher immer zum Speichern des Schlüssels verwenden, anstatt ihn fest zu codieren, wodurch eine einmalige Anmeldung erzwungen wird.
Sie sollten auch in Betracht ziehen, einen Schlüssel an einen Client zu binden. Wenn jemand dies nachahmt, sollten Sie über eine Sicherheitsschicht verfügen, die den Client, den Schlüssel und die Benutzeragenten überprüft, um die Anforderung sofort zu blockieren. Verwenden Sie einen Anwendungsfall, um sicherzustellen, dass die Schlüssel nicht nachgeahmt werden.
quelle
Wenn Sie darauf angewiesen sind, Ihren Kunden Autorisierungstoken zum Einfügen ihrer Apps zu erteilen, kann theoretisch immer jemand die App zurückentwickeln und extrahieren. Um dies zu verhindern, benötigen Sie einen Mechanismus, der kein Geheimnis in der Client-App erfordert. Das ist knifflig. Ich kann Ihnen jedoch einige Optionen vorschlagen, über die Sie nachdenken sollten.
Sie haben ein Problem, nachdem Sie die Anmeldeinformationen ausgegeben haben. Sie haben keine Kontrolle darüber, wie sicher sie gespeichert werden. Wenn der Benutzer die Anmeldeinformationen an Sie senden muss, kann jemand Ihre Verbindung MITMEN und die Token direkt stehlen, ohne sich um das Reverse Engineering der App kümmern zu müssen.
Eine Möglichkeit, das Extrahieren Ihres Autorisierungstokens zu erschweren, besteht darin, es zu verschleiern. Dies legt die Messlatte nur höher, macht es aber nicht unmöglich, und um dies zu tun, müsste man die Kontrolle über das Geheimnis behalten. Sie können eine Bibliothek implementieren, die die geheimen Informationen enthält und für jeden Kunden spezifisch ist. Sie können die Bibliothek verwenden, um mit Ihren Servern zu kommunizieren, und müssen Ihrem Benutzer möglicherweise nicht einmal die geheimen Informationen mitteilen, sondern können sie einfach in die Bibliothek einbetten. Dies löst nicht das Problem, dass jemand Ihre Bibliothek zurückentwickelt, sondern gibt Ihnen die Kontrolle über den Grad der Verschleierung. Ein Nachteil ist, dass eine Person, sobald sie die Verschleierung in der Bibliothek aufgebrochen hat, jede Ihrer Bibliotheken angreifen kann, es sei denn, Sie schreiben Code, der jede Bibliothek deutlich anders macht. Das bringt seine eigenen Probleme mit sich.
Dies kann leicht vom Umfang Ihrer Frage abweichen, aber es hängt mit der Sicherheit Ihres Tokens zusammen, also werde ich es erwähnen. Um einen unbedeutenden Diebstahl des Tokens über die Leitung zu verhindern, möchten Sie den Token wahrscheinlich nicht direkt senden, sondern können den Datenverkehr mit einer HMAC-Funktion signieren. Sie können die Gültigkeit der Nachricht überprüfen, indem Sie die HMAC der Nachricht auf dem Server berechnen und mit der vom Client gesendeten HMAC vergleichen. Sie würden das Token als Schlüssel für die HMAC-Funktion verwenden, damit nur jemand, der das Token kennt, Datenverkehr signieren kann. Dies ist besser für die Sicherheit Ihres Tokens, da Sie es niemals direkt an den Server senden, sodass es nicht direkt abgefangen und gestohlen werden kann. Weitere Informationen zu HMACS finden Sie in dieser Frage: /security/20129/how-and-when-do-i-use-hmac/20301
Keine Sicherheitslösung ist uneinnehmbar. Sie müssen entscheiden, wie viel die Implementierung kosten wird, im Vergleich zu der Wahrscheinlichkeit und den Kosten einer Gefährdung.
quelle
Zitiere dich selbst:
Das ist doch ein Widerspruch, oder? ;)
Wie andere gesagt haben, kannst du nicht. Wenn eine App einen API-Schlüssel verwendet, kann man ihn nach Belieben dekompilieren, um die Schlüssel zu erhalten und auch zu verwenden.
Abgesehen davon, dass eine zusätzliche ordnungsgemäße Benutzerauthentifizierung erforderlich ist, können Sie den Schaden nur begrenzen:
quelle