URL-Signatur mit HMAC oder OpenSSL

8

Ich bin an der URL-Signierung interessiert (zB Ссылка ), aber ich habe eine wenige Anforderungen, die mich noch ohne Lösung verlassen haben.

  • Ich werde entweder PHP oder Python für Seiten verwenden, also muss ich in der Lage sein, eine Signatur mit einem der beiden zu signieren und zu verifizieren.
  • Mein Plan war, ein Priv / Pub-Schlüsselschema zu verwenden, um einige Daten zu signieren und die Gültigkeit der Signatur überprüfen zu können, aber hier wird es kompliziert:
  • Die Daten sind nicht bekannt, wenn die Verifizierung stattfindet (es ist nicht nur somearg=value&anotherarg=anothervalue )

Mein erster Instinkt war, OpenSSL, z. mit einem RSA-Schlüsselpaar, um etwas wie Signieren zu tun: openssl rsautl -sign -inkey private.pem -in sensitive -out privsigned und Verifizieren basierend auf den privsigned -Daten und Schlüssel NUR: openssl rsautl -verify -inkey public.pem -in privsigned -pubin .

Die Verwendung von PHPs openssl_get_privatekey() und openssl_sign() signiert die Daten gut, aber ich muss die (entschlüsselten!) Daten kennen, um zu verifizieren (was ich nicht haben werde): openssl_get_publickey() und openssl_verify($data, $signature, $pubkeyid); von < a href="http://php.net/openssl_verify"> Ссылка .

Oder fehle ich hier etwas?

Also habe ich mir HMAC angeschaut, aber obwohl viele Hash-Funktionen sowohl in Python als auch in PHP verfügbar sind, bin ich verwirrt darüber, wie ich überprüfen würde der Hash. PHP 's hash_hmac() erlaubt mir, einen Hash mit einem "Schlüssel" (oder in diesem Fall einem String-Schlüssel) zu erstellen. Aber wie überprüfe ich, ob ein Hash gültig ist (d. H.% Co_de% wurde nicht nur vom Endbenutzer &sig= manuell eingegeben.)

Also zusammenfassend (Entschuldigung für die lange Frage): Wie kann ich überprüfen, ob eine Signatur / ein Hash vom Schlüssel (cert / string) meines Servers erstellt wurde (vorausgesetzt, ich kann den Hash der Daten nicht verifizieren) ? Und haben Sie irgendwelche Präferenzen, welche Route ich wählen sollte, Priv / Pub-Key oder HMAC?

Alle großen oder kleinen Hinweise werden sehr geschätzt! Vielen Dank im Voraus,

  • Josh
Josh 10.08.2011, 12:30
quelle

3 Antworten

5

HMAC ist ein symmetrischer Algorithmus, daher gibt es keinen separaten Erzeugungs- und Prüfalgorithmus. Um dies zu überprüfen, berechnen Sie einfach den Hash, wie er ursprünglich berechnet worden sein sollte, und überprüfen Sie, ob das Ergebnis dem entspricht, was Sie tatsächlich vom Client erhalten haben. Die Sicherheit ruht auf dem HMAC-Schlüssel, der nur auf Ihrem Server existiert.

Wenn Sie nicht möchten, dass die Signaturen von jemandem verifizierbar sind, der den geheimen Schlüssel nicht kennt, ist HMAC aus Gründen der Effizienz wahrscheinlich eine bessere Wahl als Systeme mit öffentlichem Schlüssel. Es kann einige Millisekunden dauern, eine öffentliche Schlüsselsignatur zu erstellen oder zu verifizieren (vor einigen Jahren habe ich eine Implementierung mit 15 ms pro Operation geplant), während HMAC ziemlich schnell ist.

(Oh, und Sie können keine Art von Signatur verifizieren, ohne die Daten zu kennen, die es signieren soll. Das würde, soweit ich das sehen kann, keinen Sinn ergeben.)

    
Henning Makholm 10.08.2011, 12:39
quelle
8
Wie Henning Makholm sagte, ist HMAC eine bessere Wahl als der öffentliche Schlüssel. Es gibt einige Best Practices, die Sie für Ihr spezielles Szenario berücksichtigen sollten, die sich auf Ihre Auswahl auswirken:

  • Möchten Sie den Hostnamen und das Schema (http / https) in der Signatur berücksichtigen? Vielleicht.
  • Möchten Sie den Pfad in der Signatur berücksichtigen? Wahrscheinlich.
  • Möchten Sie die Abfragezeichenfolge in der Signatur berücksichtigen? Wahrscheinlich.
  • Möchten Sie vor dem Signieren die Reihenfolge der Argumente und das Escaping normalisieren? Normalerweise nicht.
  • Möchten Sie die Signaturzeit usw. einbetten (um zeitlich begrenzte URLs zu erstellen)?
  • Möchten Sie die signierte URL mit einem anderen Benutzerstatus verknüpfen, z. B. Cookie?
  • Verwenden Sie von Benutzern erstellte oder für den Benutzer sichtbare Inhalte direkt im HMAC? Wenn dies der Fall ist, sollten Sie den Schlüssel mit einem Wert "salzen", der für jede Anfrage zufällig ausgewählt wird.

Wenn Sie die Signatur berechnen, müssen Sie sie URL-freundlich codieren (base64 und base32 sind beliebte Optionen) und einen HMAC-Algorithmus (wie SHA-256) auswählen und entscheiden, wie viele Bits der Signatur verwendet werden Sie möchten behalten (abgeschnitten den HMAC-Wert in der Hälfte ist in der Regel sicher). Wenn Sie sich für base64 entscheiden, achten Sie auf die verschiedenen Alphabete, die von url-safe vs. nicht-url-safe-Implementierungen verwendet werden.

Hier ist eine Pseudocode-Implementierung (ohne Fehlerprüfung oder Salzen usw.) zum Signieren von Pfad + Abfragezeichenfolge:

%Vor%

HMAC SHA256 wird empfohlen und ist in allen gängigen Sprachen verfügbar.

Java:

%Vor%

Python:

%Vor%

PHP:

%Vor%     
pawstrong 05.12.2011 08:22
quelle
0

Wenn Sie HMAC und Python verwenden möchten, dann:

$ pip installieren Sie ska

Auf der Clientseite

%Vor%

Produzierte URL sieht wie folgt aus.

Ссылка

Auf der Serverseite

Beachten Sie, dass im folgenden Beispiel request.GET als Beispiel angegeben ist. Es wird höchstwahrscheinlich von dem abweichen, was in Ihrem Framework verwendet wird (es sei denn, Sie verwenden Django).

%Vor%

Die validate_signed_request_data erzeugt ein SignatureValidationResult-Objekt, das grundsätzlich zwei Eigenschaften enthält:

  • result (bool): True, wenn Daten gültig sind. Falsch sonst.
  • Grund (Liste): Liste der Zeichenfolgen, die Validierungsfehler anzeigen.
Artur Barseghyan 02.09.2013 22:41
quelle