Mise en œuvre HMAC-SHA1 en python

j'essaie d'utiliser le langage D'un site web, qui exige que la méthode de signature soit 'HMAC-SHA1' seulement.

je me demande comment implémenter ceci en Python?

36
demandé sur Cœur 2011-12-01 12:55:56

6 réponses

Pseudocodish:

def sign_request():
    from hashlib import sha1
    import hmac

    # key = CONSUMER_SECRET& #If you dont have a token yet
    key = "CONSUMER_SECRET&TOKEN_SECRET" 


    # The Base String as specified here: 
    raw = "BASE_STRING" # as specified by oauth

    hashed = hmac.new(key, raw, sha1)

    # The signature
    return hashed.digest().encode("base64").rstrip('\n')

les erreurs de Signature résident habituellement dans la chaîne de base, assurez-vous que vous comprenez ceci (comme indiqué par L'OAuth1.0 ici: http://tools.ietf.org/html/draft-hammer-oauth-10#section-3.4.1 ).

les entrées suivantes sont utilisées pour générer la chaîne de base de Signature:

  1. méthode HTTP (par exemple GET)
  2. chemin (par exemple http://photos.example.net/photos )
  3. paramètres, Alphabétiquement, tels que (sauts de ligne pour la lisibilité):

    file=vacation.jpg
    &oauth_consumer_key=dpf43f3p2l4k3l03
    &oauth_nonce=kllo9940pd9333jh
    &oauth_signature_method=HMAC-SHA1
    &oauth_timestamp=1191242096
    &oauth_token=nnch734d00sl2jdk
    &oauth_version=1.0
    &size=original
    

le Concaténate et L'URL encodent chaque partie et finissent par:

GET&http%3A%2F%2Fphotos.example.net%2Fphotos&file%3Dvacation.jpg%26 oauth_consumer_key%3Ddpf43f3p2l4k3l03%26oauth_nonce%3Dkllo9940pd9333jh%26 oauth_signature_method%3DHMAC-SHA1%26oauth_timestamp%3D1191242096%26 oauth_token%3Dnnch734d00sl2jdk%26oauth_version%3D1.0%26size%3Doriginal

66
répondu Jon Nylander 2016-07-02 19:25:23

pour L'amour de Dieu, si vous faites quelque chose avec oauth, utilisez la bibliothèque requests pour Python! J'ai essayé d'implémenter HMAC-SHA1 en utilisant la bibliothèque hmac en Python et c'est beaucoup de maux de tête, essayer de créer la bonne chaîne de base outh et ainsi de suite. Il suffit d'utiliser les requêtes et c'est aussi simple que:

>>> import requests
>>> from requests_oauthlib import OAuth1

>>> url = 'https://api.twitter.com/1.1/account/verify_credentials.json'
>>> auth = OAuth1('YOUR_APP_KEY', 'YOUR_APP_SECRET', 'USER_OAUTH_TOKEN', 'USER_OAUTH_TOKEN_SECRET')

>>> requests.get(url, auth=auth)

Les Demandes D'Authentification

Les Demandes D'Authentification Oauth Bibliothèque

11
répondu Blairg23 2015-08-18 05:52:51
7
répondu Andrey Atapin 2015-08-05 06:59:59

enfin voici une solution qui fonctionne (testée avec Python 3) en utilisant oauthlib .

j'utilise le premier pas donné comme exemple dans le RTF officiel 1 :

Client Identifier: dpf43f3p2l4k3l03
Client Shared-Secret: kd94hf93k423kf44

POST /initiate HTTP/1.1
Host: photos.example.net
Authorization: OAuth realm="Photos",
    oauth_consumer_key="dpf43f3p2l4k3l03",
    oauth_signature_method="HMAC-SHA1",
    oauth_timestamp="137131200",
    oauth_nonce="wIjqoS",
    oauth_callback="http%3A%2F%2Fprinter.example.com%2Fready",
    oauth_signature="74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D"

la valeur pour oauth_signature est ce que nous aimerions calculer.

ce qui suit définit ce que nous voulons signer:

# There is no query string present.
# In case of http://example.org/api?a=1&b=2 - the value
# would be "a=1&b=2".
uri_query=""

# The oauthlib function 'collect_parameters' automatically
# ignores irrelevant header items like 'Content-Type' or
# 'oauth_signature' in the 'Authorization' section.
headers={
    "Authorization": (
        'OAuth realm="Photos", '
        'oauth_nonce="wIjqoS", '
        'oauth_timestamp="137131200", '
        'oauth_consumer_key="dpf43f3p2l4k3l03", '
        'oauth_signature_method="HMAC-SHA1", '
        'oauth_callback="http://printer.example.com/ready"'
    )
}

# There's no POST data here - in case it was: x=1 and y=2,
# then the value would be '[("x","1"),("y","2")]'.
data=[]

# This is the above specified client secret which we need
# for calculating the signature.
client_secret="kd94hf93k423kf44"

et nous y voilà:

import oauthlib.oauth1.rfc5849.signature as oauth

params = oauth.collect_parameters(
    uri_query="",
    body=data, 
    headers=headers,
    exclude_oauth_signature=True, 
    with_realm=False
)

norm_params = oauth.normalize_parameters(params)

base_string = oauth.construct_base_string(
    "POST", 
    "https://photos.example.net/initiate", 
    norm_params
)

sig = oauth.sign_hmac_sha1(
    base_string, 
    client_secret, 
    '' # resource_owner_secret - not used
)

from urllib.parse import quote_plus

print(sig)
# 74KNZJeDHnMBp0EMJ9ZHt/XKycU=

print(quote_plus(sig))
# 74KNZJeDHnMBp0EMJ9ZHt%2FXKycU%3D
2
répondu Raffael 2016-09-14 15:46:18

il existe plusieurs bibliothèques python disponibles sur le site Web de oauth , mais si vous êtes simplement intéressé par une implémentation spécifique, vous pouvez jeter un oeil à l'une d'elles .

1
répondu Till 2011-12-01 09:05:10

Vous pouvez essayer la méthode suivante.

def _hmac_sha1(input_str):
        raw = input_str.encode("utf-8")
        key = 'your_key'.encode('utf-8')
        hashed = hmac.new(key, raw, hashlib.sha1)
        return base64.encodebytes(hashed.digest()).decode('utf-8')
0
répondu Qy Zuo 2017-06-29 09:51:03