2012-03-29 12 views
2

Ich habe die API-Kommunikation gelesen und versucht herauszufinden, wie eine sichere API am besten aufgebaut werden kann. Ich weiß, dass OAuth und solche existieren, aber ich versuche auch, mich in diesem Prozess zu bilden und mich nicht auf Bibliotheken zu verlassen.Schutz vor Replay-Angriffen bei Verwendung von Anforderungssignaturen in sicherer API-Kommunikation?

Grundsätzlich habe ich einen Web-Service und in diesem Web-Service können Benutzer für API registrieren. Sie erhalten eine Profil-ID und einen geheimen Schlüssel, den sie verwenden müssen, um die API-Anfrage von einem anderen Web-System zu erstellen.

API-Anfrage ähnlich wie die Art und Weise gebaut Banken es tun, werden alle Eingabedaten an API gesendet sortiert werden, Hash berechnet und dann den Hash an den Server gesendet, wie folgt aus:

// Profile data 
$apiProfile='api123'; 
$apiSecret='this-is-a-good-day-to-be-a-secret-key'; 

// Input 
$input=array(); 
$input['name']='Thomas Moore'; 
$input['profession']='Baker'; 

// To ensure that the order of variables checked and received is the same on both ends: 
ksort($input); 

// Using serialize() for simplifying things 
// http_build_query() is another option, or just placing values in order 
$input['hash']=sha1(serialize($input).$apiSecret); 

// Making a request to URL: 
// Using file_get_contents() as an example, would use cURL otherwise 
$result=file_get_contents('http://www.example.com/api.php?'.http_build_query($input)); 

// SERVER CALCULATES COMPARISON HASH BASED ON KNOWN SECRET KEY AND INPUT DATA 

Diese ist wirklich gut und funktioniert. Aber! Mein Problem ist der mögliche Replay-Angriff. Wenn jemand diese Anforderungs-URL abruft, kann er sie erneut an den Server senden, obwohl sie die Daten selbst nicht ändern kann.

Jetzt habe ich ein paar Dinge darüber gelesen, dass Sie entweder die Zeit überprüfen oder ein einmal benutztes Token zu der Anfrage hinzufügen sollten, aber ich bin mir nicht sicher, wie genau soll ich das machen? Senden Sie einen Zeitstempel mit der Anfrage wirklich sicher genug? (Der empfangende Server würde sicherstellen, dass die Anfrage wenige Sekunden innerhalb der Zeit, in der die Anfrage gemacht wurde, entstanden ist, wenn die Uhren etwas synchron sind).

Ich könnte dem Mix auch IP-Validierungen hinzufügen, aber diese können sich ändern und können etwas gefälscht werden und sind für den Benutzer mühsamer.

Ich würde diesen One-Time-Token-Systemtyp lieben, aber ich bin mir nicht sicher, wie das geht, ohne die Token-Generierung dem exakt gleichen Replay-Angriffs-Problem auszusetzen? (Das letzte, was ich brauche, ist es, sichere Tokens für Mittelmänner zu vergeben).

Meinungen und Artikel wären wirklich willkommen, ich konnte kein Material finden, das meine spezifischen Anliegen beantwortet. Ich möchte sagen, dass meine API sicher ist, ohne dass es nur Marketing ist.

Vielen Dank!

Antwort

3

Sie müssen den Austausch von Token nur über einen sicheren Kanal (https) zulassen, und Sie sollten einen eindeutigen Hash pro Nachricht haben. Fügen Sie Dinge wie einen Zeitstempel und die IP des Clients ein. Wenn Sie keine https verwenden, sind Sie anfällig für einen Angriff im Stil von FireSeep.

Ansonsten machen Sie die Token-Generierung und den Austausch korrekt.

+0

Vielen Dank für das Votum des Vertrauens, ich bin nur ein paranoider Perfektionist, nehme ich an. – kingmaple

+0

Ich könnte einen tatsächlichen HMAC verwenden, um Angriffe mit Längenverlängerung zu vermeiden, obwohl es so aussieht, als ob Sie nicht verwundbar sind, da Sie das Geheimnis als letztes und nicht als erstes platzieren. http://en.wikipedia.org/wiki/Hmac http://en.wikipedia.org/wiki/Length_extension_attack – alberge

2

Senden der Zeit (und es in den Cache) ist wirklich eine Option. Die andere Option wäre ein 2-Phasen-Algorithmus, wenn Sie zum ersten Mal nach dem Sitzungstoken oder einem Sitzungsschlüssel fragen, diesen dann für die Sitzung verwenden und dessen TTL auf dem Server gespeichert wird (z. B. Uhrzeit oder Anzahl der Anfragen) erlaubt)

wie für den Sitzungsschlüssel Idee Blick auf Programme wie http://en.wikipedia.org/wiki/Diffie%E2%80%93Hellman_key_exchange

Beispiel 1-Zeit-Token-Algorithmus:

1) Client eine Anforderung für die 1-Zeit-Token komponiert, Zeichen dieses Antrag mit den geheimen Schlüssel und sendet es an den Server.

2) Server erzeugt den Schlüssel, es Zeichen mit dem gleichen Schlüssel und sendet sie an den Client (zusammen mit der Signatur)

3) Client überprüft das Token den geheimen Schlüssel

4)-Client verfasst die Anfrage, einschließlich des Tokens, und signiert den gesamten Anfragekörper mit dem geheimen Schlüssel und sendet dann an den Server

5) Der Server prüft die Integrität des gesamten Körpers und die Token-Gültigkeit und sendet dann die Antwort (erneut signiert mit dem geheimen Schlüssel für Integrität und Autorenverifizierung)

+1

Timestamp Lösung scheint wirklich zweifelhaft. Da mein API-Framework und die Bibliothek, die damit kommunizieren, beide Open Source sind, könnte ein Mann in der Mitte einen Listener bauen, der genau die gleiche Anfrage innerhalb der begrenzten 'Timestamp'-Zeit empfängt und dafür ein Authentifizierungs-Token erhält. Das möchte ich möglichst vermeiden. – kingmaple

+0

sehen Sie ein Update für die 2-Phasen-API mit dem 1-Zeit-Token. auch Sie können die Kommunikation vollständig mit Diffie-Hellman oder ähnlichen Sitzungsschlüssel Ansatz – Guard

+0

verschlüsseln Wenn Sie die Transaktion in TLS wickeln, erreicht das die gleiche Sache. –