Wie stelle ich sicher, dass meine REST-API nur auf Anforderungen von vertrauenswürdigen Clients reagiert, in meinem Fall auf meine eigenen mobilen Anwendungen? Ich möchte unerwünschte Anfragen aus anderen Quellen verhindern. Ich möchte nicht, dass Benutzer einen Serienschlüssel oder was auch immer ausfüllen. Dies sollte hinter den Kulissen, bei der Installation und ohne Benutzereingriff geschehen.
Meines Wissens dient HTTPS nur dazu, den Server zu überprüfen, mit dem Sie kommunizieren. Ich werde natürlich HTTPS verwenden, um die Daten zu verschlüsseln.
Gibt es eine Möglichkeit, dies zu erreichen?
Update: Der Benutzer kann schreibgeschützte Aktionen ausführen, bei denen der Benutzer nicht angemeldet sein muss. Er kann jedoch auch Schreibaktionen ausführen, bei denen der Benutzer angemeldet sein muss (Authentifizierung durch Zugriffstoken). In beiden Fällen möchte ich, dass die API auf Anfragen reagiert, die nur von vertrauenswürdigen mobilen Anwendungen stammen.
Die API wird auch zum Registrieren eines neuen Kontos über die mobile Anwendung verwendet.
Update 2: Es scheint, als gäbe es mehrere Antworten darauf, aber ich weiß ehrlich gesagt nicht, welche ich als Antwort markieren soll. Einige sagen, es kann getan werden, andere sagen, es kann nicht.
Antworten:
Das kannst du nicht.
Sie können niemals eine Entität oder eine Entität überprüfen , sei es eine Person, ein Hardware-Client oder ein Software-Client. Sie können nur überprüfen, ob das, was sie Ihnen sagen , korrekt ist, und dann von Ehrlichkeit ausgehen .
Woher weiß Google beispielsweise, dass ich mich in meinem Google Mail-Konto anmelde? Sie fragen mich einfach nach einem Benutzernamen und einem Passwort, überprüfen das und gehen dann von Ehrlichkeit aus, denn wer sonst hätte diese Informationen? Irgendwann entschied Google, dass dies nicht ausreicht, und fügte eine Verhaltensüberprüfung hinzu (auf der Suche nach ungewöhnlichem Verhalten), die sich jedoch weiterhin darauf stützt, dass die Person das Verhalten ausführt und anschließend das Verhalten validiert .
Dies ist genau das gleiche wie bei der Validierung des Clients. Sie können nur das Verhalten des Clients überprüfen, nicht jedoch den Client selbst.
Mit SSL können Sie also überprüfen, ob der Client ein gültiges Zertifikat hat oder nicht. Sie können also einfach Ihre App installieren, das Zertifikat erhalten und dann den gesamten neuen Code ausführen.
Die Frage ist also: Warum ist das so kritisch? Wenn dies ein echtes Problem ist, würde ich Ihre Wahl eines fetten Kunden in Frage stellen. Vielleicht sollten Sie eine Web-App verwenden (damit Sie Ihre API nicht offenlegen müssen).
Siehe auch: Deaktivieren der SSL-Zertifikatüberprüfung für Android-Anwendungen
und: Wie sicher sind Client-SSL-Zertifikate in einer mobilen App?
quelle
Ich bin mir sicher, dass Sie mit dem Umgang mit Benutzeranmeldungen und der Kommunikation über SSL vertraut sind. Daher werde ich mich auf den meiner Meinung nach interessanteren Teil der Frage konzentrieren: Wie stellen Sie sicher, dass Ihre schreibgeschützten Aktionen - die Sie nicht benötigen die Benutzer authentifiziert werden - werden nur von Ihren eigenen Client - Anwendungen akzeptiert?
Vor allem gibt es den Nachteil, auf den fNek in einer früheren Antwort hingewiesen hat: Ihre Client-Apps befinden sich in den Händen potenziell feindlicher Benutzer. Sie können untersucht, ihre Kommunikation überprüft und ihr Code zerlegt werden. Mit keinem meiner Vorschläge können Sie garantieren, dass jemand Ihren Client nicht zurückentwickelt und Ihre REST-API missbraucht. Aber es sollte eine Barriere vor zufälligen Versuchen setzen.
Wie auch immer, ein gängiger Ansatz ist:
Stellen Sie sich zB eine
GET
Anfrage für vor/products/widgets
Angenommen, das Client-Geheimnis lautet "OH_HAI_I_IZ_SECRET".
Verketten Sie das HTTP-Verb, die URL und das Geheimnis:
Und nimm einen SHA-1- Hash davon:
Dann sende das mit, so wäre die Anfrage für:
Um zu verhindern, dass jemand einzelne Anforderungen zumindest wiederholt, nehmen Sie auch einen Zeitstempel und fügen Sie diesen den Parametern und dem Hash hinzu. ZB ist momentan in der Unix-Zeit 1384987891. Fügen Sie dies zur Verkettung hinzu:
Hasch das:
Und senden:
Der Server überprüft den Hash und stellt auch sicher, dass der Zeitstempel aktuell ist (z. B. innerhalb von 5 Minuten, um zu gewährleisten, dass die Uhren nicht perfekt synchron sind).
Warnung! Da es sich um mobile Apps handelt, besteht definitiv das Risiko, dass auf dem Telefon eines anderen eine falsche Uhrzeit angezeigt wird. Oder Zeitzone falsch. Oder so. Das Hinzufügen der Zeit zum Hash wird wahrscheinlich einige legitime Benutzer zum Scheitern bringen. Verwenden Sie diese Idee daher mit Vorsicht.
quelle
Für alle Interessierten können Sie unter Android überprüfen, ob die von Ihnen erhaltene Anfrage von Ihrer App gesendet wurde.
Kurz gesagt, wenn Sie Ihre App auf Google hochladen, signieren Sie sie mit einem eindeutigen Schlüssel, der nur Ihnen (und Google) bekannt ist.
Der Verifizierungsprozess läuft wie folgt ab:
Das vollständige Blog, in dem es erklärt und wie es implementiert wird, finden Sie hier: http://android-developers.blogspot.co.il/2013/01/verifying-back-end-calls-from-android.html
quelle
Ok, es ist also erwähnenswert, bevor ich anfange, dass dies für die meisten Anwendungen ein enormer Übermaß ist. In den meisten Fällen ist es mehr als ausreichend, nur ein einziges gültiges Zertifikat und / oder Token zu haben. Wenn es darum geht, Ihre App zu dekompilieren, werden sich selbst die meisten Hacker nicht darum kümmern, es sei denn, Sie geben einige sehr wertvolle Daten an. Aber was macht die Antwort für einen Spaß?
Sie können also eine asymmetrische Kryptographie einrichten, ähnlich wie digitale Signaturen, die zum Signieren von Programmen verwendet werden. Jede App kann dann über ein einzelnes Zertifikat verfügen, das von einer einzelnen Zertifizierungsstelle ausgestellt und überprüft wird, wenn Ihr Benutzer eine Verbindung herstellt. (entweder bei der erstmaligen Registrierung oder bei der Erstinstallation) Wenn dieses Zertifikat authentifiziert ist, können Sie Ihre Anwendung weiter sichern, indem Sie dieses Zertifikat als gültig für eine bestimmte Gerätekennung (z. B. Android-ID ) registrieren.
quelle
Wie @ Morons in seiner Antwort erwähnt hat, ist es sehr schwierig, die Entität am anderen Ende der Verbindung zu überprüfen.
Der einfachste Weg, ein gewisses Maß an Authentizität bereitzustellen, besteht darin, den Server ein Geheimnis überprüfen zu lassen, das nur die reale Entität kennen würde. Für einen Benutzer kann dies ein Benutzername und ein Kennwort sein. Für eine Software, für die es keinen Benutzer gibt, können Sie ein Geheimnis einbetten.
Das Problem bei diesen Ansätzen ist, dass Sie dem Kunden etwas Vertrauen schenken müssen. Wenn jemand Ihre App zurückentwickelt oder Ihr Passwort stiehlt, kann er sich als Sie ausgeben.
Sie können Schritte unternehmen, um das Extrahieren der geheimen Informationen zu erschweren, indem Sie sie in der ausführbaren Datei verschleiern. Tools wie ProGuard, ein Obfuscator für Java, können dabei helfen. Ich weiß nicht so viel über die Verschleierung in anderen Sprachen, aber es gibt wahrscheinlich ähnliche Tools. Durch die Verwendung einer TLS-Verbindung können Sie verhindern, dass Personen Ihren Datenverkehr ausspähen, jedoch keinen MITM-Angriff. Das Fixieren kann dabei helfen, dieses Problem zu beheben .
Ich arbeite für ein Unternehmen namens CriticalBlue (Full Disclosure!) Mit einem Produkt namens Approov , das versucht, dieses Vertrauensproblem anzugehen. Es funktioniert derzeit für Android / iOS und bietet unseren Servern einen Mechanismus, um die Integrität der Client-App zu überprüfen. Dies geschieht, indem der Client eine Antwort auf eine zufällige Herausforderung berechnet. Der Client muss die Antwort unter Verwendung von schwer zu fälschenden Attributen des installierten App-Pakets berechnen und enthält einige ausgefeilte Manipulationsschutzmechanismen.
Es wird ein Token zurückgegeben, das Sie als Echtheitsnachweis an Ihre API senden können.
Der wichtige Unterschied bei diesem Ansatz besteht darin, dass die Authentizitätsprüfung auf dem Client zwar deaktiviert werden kann, Sie jedoch nicht das Authentifizierungstoken erhalten, das Sie zur Überprüfung Ihrer App beim Server benötigen. Die Bibliothek ist außerdem eng an die Eigenschaften der ausführbaren Datei gekoppelt, in der sie sich befindet. Daher wäre es sehr schwierig, sie in eine gefälschte App einzubetten und funktionsfähig zu machen.
Es gibt eine Kosten-Nutzen-Analyse, die jeder API-Entwickler durchführen muss, um zu entscheiden, wie wahrscheinlich es ist, dass jemand versucht, seine API zu hacken, und wie teuer dies sein könnte. Eine einfache geheime Prüfung in der Anwendung verhindert triviale Angriffe, aber sich gegen einen entschlosseneren Angreifer zu schützen, ist wahrscheinlich erheblich komplizierter und möglicherweise kostspieliger.
quelle
SSL sichert den Kommunikationskanal.
Bei erfolgreicher Anmeldung wird ein Authentifizierungstoken über eine verschlüsselte Verbindung ausgegeben.
Das Authentifizierungstoken wird bei allen nachfolgenden Anforderungen an Ihre REST-API übergeben.
quelle
Es wäre nicht zu sicher, aber Sie könnten eine Art Geheimcode oder sogar eine digitale Signatur hinzufügen. Nachteil: Es muss in der App enthalten sein, was es einfach macht, es zu erhalten, wenn Sie wissen, was Sie tun.
quelle
Tatsächlich können Sie SSL verwenden, um sowohl den Client als auch den Server zu authentifizieren. Oder anders ausgedrückt: "Ja, Sie können Client-Zertifikate verwenden".
Sie müssen ...
Sie können die mobile Anwendung das Zertifikat speichern lassen, wo immer Sie möchten. Da Sie eine anwendungsspezifische Authentifizierung wünschen, sollten Sie erwägen, das Zertifikat an einem geschützten Speicherort auf der Festplatte zu speichern (unter Android können Sie eine "config" -Tabelle in Ihrer SQLite-Datenbank und eine Zeile für Ihr Zertifikat und eine andere für Ihren privaten Schlüssel erstellen). .
quelle