9
votes

URL Signature avec HMAC ou OpenSSL

Je suis intéressé par la signature d'URL (par exemple http: //.../ somearg = valeur & anotherarg = uneautrevaleur & sig = aSKS9F3KL5xc ), mais j'ai quelques exigences qui me ont laissé sans solution encore.

  • Je vais utiliser soit PHP ou Python pour les pages, donc je vais devoir être en mesure de signer et vérifier une signature en utilisant l'un des deux. < / li>
  • Mon plan était d'utiliser un système de clé PRIV / pub pour signer des données, et être en mesure de vérifier que la signature est valide, mais voici où ça se complique:
  • Les données ne sait pas quand la vérification se passe (il est non seulement somearg = valeur & anotherarg = uneautrevaleur )

    Mon premier instinct était d'utiliser OpenSSL, par exemple avec une paire de clés RSA, de faire quelque chose le long des lignes de signature par: OpenSSL rsautl --sign -inkey private.pem -in sensibles privsigned -out et la vérification en fonction du privsigned données et touche seulement:. OpenSSL rsautl -verify -inkey public.pem -En privsigned -pubin

    Utilisation PHP openssl_get_privatekey () et openssl_sign () signe les données très bien, mais je dois connaître les données (déchiffré!) Afin de vérifier (que je aura pas): openssl_get_publickey () et openssl_verify (données $, signature $, $ pubkeyid); http://php.net/openssl_verify .

    Ou suis-je manque quelque chose ici?


    Je regardé dans HMAC, mais bien que la fonction de hachage beaucoup sont disponibles dans les deux Python et PHP , je suis dérouté quant à la façon dont je vais sur les Verifying le hachage. PHP 's hash_hmac () me permet de créer un hachage en utilisant une "clé" (ou dans ce cas une clé de chaîne). Mais comment puis-je faire pour vérifier qu'un hachage est valide (par exemple & sig = n'a pas seulement été mis manuellement par l'utilisateur final & sig = abcdefg1234 .

    Donc, pour résumer (désolé pour la longue question): Comment puis-je vérifier qu'une signature / hachage a été faite par ma clé de serveur (cert / string) (étant donné que je ne peux pas vérifier en refaisant le hachage desdites données) ? Et avez-vous des préférences quant à la route que je voulais, Priv / pub-clé ou HMAC?

    Les pointeurs grand ou petit est grandement appréciée! Merci à l'avance,

    • Josh

0 commentaires

3 Réponses :


8
votes

HMAC est un algorithme symétrique, donc il n'y a pas de création séparée et algorithme de vérification. Pour vérifier, vous calculer simplement le hachage comme il aurait dû être calculé à l'origine, et vérifier que le résultat est égal à ce que vous avez réellement obtenu du client. Les restes de sécurité sur la clé HMAC uniquement existant sur votre serveur.

Sauf si vous avez besoin des signatures pour être vérifiables par quelqu'un qui ne pas connaître la clé secrète, HMAC est probablement un meilleur choix que les systèmes à clé publique, pour des raisons d'efficacité. Il peut prendre plusieurs millisecondes pour créer ou vérifier une signature à clé publique (il y a je l'ai chronométré une mise en œuvre quelques années à 15 ms par opération), alors que HMAC est assez rapide.

(Oh, et vous ne pouvez pas vérifier tout type de signature sans connaître les données qu'il est censé signer. Ce ne serait pas de sens, pour autant que je peux voir).


2 commentaires

Merci pour le nettoyage cela. Je pensais que ce serait peu sûr de faire simplement un hachage de « statique », par exemple hachage (url) (ou hachage (sel + url)). L'utilisation du temps dans le hachage serait très difficile alors, et les paramètres finirait par devenir connu.


Eh bien, cela dépend de ce que vous essayez de vous protéger, ce qui n'est pas clair de votre question. En règle générale, il y aurait un paramètre de temps de génération dans l'URL inclus dans l'entrée HASH et vérifié de telle sorte que vous puissiez rejeter les URL stables.



11
votes

Comme Henning Makholm a souligné, HMAC est un meilleur choix que la clé publique. Il y a quelques bonnes pratiques que vous devriez considérer pour votre scénario particulier qui aura un impact sur vos choix:

  • Est-ce que vous voulez examiner le nom d'hôte et le schéma (http / https) dans la signature? Peut-être. Li>
  • Est-ce que vous voulez examiner le chemin dans la signature? Probablement. Li>
  • Est-ce que vous voulez examiner la chaîne de requête dans la signature? Probablement. Li>
  • Est-ce que vous voulez normaliser l'ordre d'arguments et d'échapper avant la signature? Généralement pas. Li>
  • Voulez-vous le temps de signature, etc Embed (pour créer des URL limitées dans le temps)? Li>
  • Est-ce que vous voulez lier l'URL signé à un autre état de l'utilisateur, comme le cookie? Li>
  • Utilisez-vous le contenu généré par l'utilisateur ou visible par l'utilisateur directement dans le HMAC? Si oui, vous devriez « sel » la clé en utilisant une valeur qui est aléatoire pour chaque demande. Li> Ul>

    Lors du calcul de la signature, vous aurez besoin de coder d'une manière conviviale URL (base64 et base32 sont des choix populaires) et choisissez un algorithme HMAC (tel que SHA-256), et de décider combien de bits de la signature que vous souhaitez conserver (tronquer la valeur HMAC dans la moitié est généralement sans danger). Si vous choisissez base64, méfiez-vous des différents alphabets utilisés par sécurité url vs implémentations non-url de sécurité. P>

    Voici une implémentation pseudocode (w / o vérification des erreurs ou salage, etc.) pour le chemin signature + requête chaîne:. p>

    hash_hmac("sha256", value, secret);
    


0 commentaires

0
votes

Si vous voulez utiliser HMAC et Python, puis:

$ pip installer ska p>

Du côté client h2>
from ska import validate_signed_request_data

validation_result = validate_signed_request_data(
    data = request.GET, # Note, that ``request.GET`` is given as example.
    secret_key = 'your-secret_key'
)


0 commentaires