Hintergrund:
Ich entwerfe das Authentifizierungsschema für einen REST-Webdienst. Dies muss nicht "wirklich" sicher sein (es ist eher ein persönliches Projekt), aber ich möchte es so sicher wie möglich machen, wie eine Übung / Lernerfahrung. Ich möchte kein SSL verwenden, da ich den Aufwand und vor allem die Kosten für die Einrichtung nicht möchte.
Diese SO-Fragen waren besonders nützlich, um mir den Einstieg zu erleichtern:
- RESTful Authentifizierung
- Best Practices zum Sichern einer REST-API / eines Webdienstes
- Beispiele für die besten SOAP / REST / RPC-Web-APIs? Und warum magst du sie? Und was ist los mit ihnen?
Ich denke darüber nach, eine vereinfachte Version der Amazon S3-Authentifizierung zu verwenden (ich mag OAuth, aber es scheint für meine Anforderungen zu kompliziert zu sein). Ich füge der Anforderung eine zufällig generierte Nonce hinzu , die vom Server bereitgestellt wird, um Wiederholungsangriffe zu verhindern.
Um auf die Frage zu kommen:
Sowohl S3 als auch OAuth müssen die Anforderungs-URL zusammen mit einigen ausgewählten Headern signieren. Keiner von beiden signiert den Anforderungshauptteil für POST- oder PUT-Anforderungen. Ist dies nicht anfällig für einen Man-in-the-Middle-Angriff, bei dem die URL und die Header beibehalten und der Anforderungshauptteil durch die vom Angreifer gewünschten Daten ersetzt werden?
Es scheint, als könnte ich mich dagegen schützen, indem ich einen Hash des Anforderungshauptteils in die Zeichenfolge einbinde, die signiert wird. Ist das sicher?
Antworten:
In einer früheren Antwort wurde SSL nur im Zusammenhang mit der Datenübertragung erwähnt und nicht die Authentifizierung behandelt.
Sie fragen wirklich nach der sicheren Authentifizierung von REST-API-Clients. Sofern Sie nicht die TLS-Clientauthentifizierung verwenden, ist SSL allein KEIN praktikabler Authentifizierungsmechanismus für eine REST-API. SSL ohne Clientauthentifizierung authentifiziert nur den Server , was für die meisten REST-APIs irrelevant ist, da Sie den Client wirklich authentifizieren möchten .
Wenn Sie keine TLS-Clientauthentifizierung verwenden, müssen Sie ein Digest-basiertes Authentifizierungsschema (wie das benutzerdefinierte Schema von Amazon Web Service) oder OAuth 1.0a oder sogar eine HTTP Basic-Authentifizierung (jedoch nur über SSL) verwenden.
Diese Schemata bestätigen, dass die Anforderung von einer erwarteten Person gesendet wurde. TLS (SSL) (ohne Clientauthentifizierung) stellt sicher, dass die über das Kabel gesendeten Daten nicht manipuliert werden. Sie sind getrennte - aber komplementäre - Anliegen.
Für Interessenten habe ich eine SO-Frage zu HTTP-Authentifizierungsschemata und deren Funktionsweise erweitert .
quelle
REST bedeutet, mit den Standards des Webs zu arbeiten, und der Standard für die "sichere" Übertragung im Web ist SSL. Alles andere wird irgendwie funky und erfordert zusätzlichen Bereitstellungsaufwand für Clients, für die Verschlüsselungsbibliotheken verfügbar sein müssen.
Sobald Sie sich für SSL entschieden haben, ist für die Authentifizierung im Prinzip wirklich nichts Besonderes erforderlich. Sie können wieder Webstandards verwenden und die HTTP Basic-Authentifizierung (Benutzername und geheimes Token, die zusammen mit jeder Anforderung gesendet werden) verwenden, da dies viel einfacher als ein ausgeklügeltes Signaturprotokoll ist und im Kontext einer sicheren Verbindung immer noch wirksam ist. Sie müssen nur sicherstellen, dass das Passwort niemals über Klartext geht. Wenn das Kennwort jemals über eine Nur-Text-Verbindung empfangen wird, können Sie das Kennwort sogar deaktivieren und dem Entwickler eine E-Mail senden. Sie sollten auch sicherstellen, dass die Anmeldeinformationen beim Empfang nirgendwo protokolliert werden, genauso wie Sie kein reguläres Kennwort protokollieren würden.
HTTP Digest ist ein sicherer Ansatz, da verhindert wird, dass das geheime Token weitergegeben wird. Stattdessen ist es ein Hash, den der Server am anderen Ende überprüfen kann. Wenn Sie die oben genannten Vorsichtsmaßnahmen getroffen haben, kann dies für weniger empfindliche Anwendungen zu viel des Guten sein. Schließlich wird das Kennwort des Benutzers bereits bei der Anmeldung im Klartext übertragen (es sei denn, Sie führen eine ausgefallene JavaScript-Verschlüsselung im Browser durch), und ebenso die Cookies bei jeder Anfrage.
Beachten Sie, dass es bei APIs für den Client besser ist, Token - zufällig generierte Zeichenfolgen - anstelle des Kennworts zu übergeben, mit dem sich der Entwickler auf der Website anmeldet. Der Entwickler sollte sich also bei Ihrer Site anmelden und neue Token generieren können, die für die API-Überprüfung verwendet werden können.
Der Hauptgrund für die Verwendung eines Tokens besteht darin, dass es ersetzt werden kann, wenn es kompromittiert wird. Wenn das Kennwort kompromittiert wird, kann sich der Eigentümer beim Entwicklerkonto anmelden und alles tun, was er will. Ein weiterer Vorteil von Token besteht darin, dass Sie mehrere Token an dieselben Entwickler ausgeben können. Vielleicht, weil sie mehrere Apps haben oder weil sie Token mit unterschiedlichen Zugriffsebenen wollen.
(Aktualisiert, um die Auswirkungen der Herstellung der Verbindung nur auf SSL abzudecken.)
quelle
Oder Sie können die bekannte Lösung für dieses Problem verwenden und SSL verwenden. Selbstsignierte Zertifikate sind kostenlos und ein persönliches Projekt, oder?
quelle
Wenn Sie den Hash des Körpers als einen der Parameter in der URL benötigen und diese URL über einen privaten Schlüssel signiert ist, kann ein Man-in-the-Middle-Angriff den Körper nur durch Inhalte ersetzen, die den generieren gleicher Hash. Zumindest mit MD5-Hashwerten ist das jetzt einfach und wenn SHA-1 kaputt ist, erhalten Sie das Bild.
Um den Körper vor Manipulationen zu schützen, müssten Sie eine Signatur des Körpers benötigen, die bei einem Man-in-the-Middle-Angriff mit geringerer Wahrscheinlichkeit unterbrochen werden kann, da sie den privaten Schlüssel, der die Signatur generiert, nicht kennen .
quelle
Tatsächlich ermöglicht die ursprüngliche S3-Authentifizierung das Signieren des Inhalts, wenn auch mit einer schwachen MD5-Signatur. Sie können einfach die optionale Vorgehensweise erzwingen, einen Content-MD5-Header in die HMAC aufzunehmen (zu signierende Zeichenfolge).
http://s3.amazonaws.com/doc/s3-developer-guide/RESTAuthentication.html
Das neue v4-Authentifizierungsschema ist sicherer.
http://docs.aws.amazon.com/general/latest/gr/signature-version-4.html
quelle
Denken Sie daran, dass Ihre Vorschläge es Clients erschweren, mit dem Server zu kommunizieren. Sie müssen Ihre innovative Lösung verstehen und die Daten entsprechend verschlüsseln. Dieses Modell eignet sich nicht so gut für öffentliche APIs (es sei denn, Sie sind amazon \ yahoo \ google ..).
Wenn Sie den Inhalt des Körpers verschlüsseln müssen, würde ich Ihnen empfehlen, vorhandene Standards und Lösungen zu überprüfen, z.
XML-Verschlüsselung (W3C-Standard)
XML-Sicherheit
quelle