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?
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:
- méthode HTTP (par exemple GET)
- chemin (par exemple http://photos.example.net/photos )
-
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
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)
C'est déjà là Keyed-de Hachage pour l'Authentification de Message
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
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 .
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')