Calculating a SHA hash with a string + secret key in python
Asked Answered
U

6

59

Amazon Product API now requires a signature with every request which I'm trying to generate ushing Python.

The step I get hung up on is this one:

"Calculate an RFC 2104-compliant HMAC with the SHA256 hash algorithm using the string above with our "dummy" Secret Access Key: 1234567890. For more information about this step, see documentation and code samples for your programming language."

Given a string and a secret key (in this case 1234567890) how do I calculate this hash using Python?

----------- UPDATE -------------

The first solution using HMAC.new looks correct however I'm getting a different result than they are.

http://docs.amazonwebservices.com/AWSECommerceService/latest/DG/index.html?rest-signature.html

According to Amazon's example when you hash the secret key 1234567890 and the following string

GET
webservices.amazon.com
/onca/xml
AWSAccessKeyId=00000000000000000000&ItemId=0679722769&Operation=I
temLookup&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReview
s&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&
Version=2009-01-06

You should get the following signature: 'Nace+U3Az4OhN7tISqgs1vdLBHBEijWcBeCqL5xN9xg='

I am getting this: '411a59403c9f58b4a434c9c6a14ef6e363acc1d1bb2c6faf9adc30e20898c83b'

Ursulina answered 20/8, 2009 at 14:23 Comment(1)
You can find this one useful. The algorithm of signing a REST request to Amazon is described in https://mcmap.net/q/131126/-how-to-sign-amazon-web-service-requests-from-the-python-app-engine/1343917#1343917Rameriz
P
111
import hmac
import hashlib
import base64
dig = hmac.new(b'1234567890', msg=your_bytes_string, digestmod=hashlib.sha256).digest()
base64.b64encode(dig).decode()      # py3k-mode
'Nace+U3Az4OhN7tISqgs1vdLBHBEijWcBeCqL5xN9xg='
Principe answered 20/8, 2009 at 14:27 Comment(1)
Thanks. This looks correct but I am not yielding the same results as Amazon. See the update above.Ursulina
H
20
import hmac
import hashlib
import base64

digest = hmac.new(secret, msg=thing_to_hash, digestmod=hashlib.sha256).digest()
signature = base64.b64encode(digest).decode()

I know this sounds silly, but make sure you don't have a trailing space on your secret by accident.

Heteropolar answered 28/8, 2012 at 19:13 Comment(1)
the secret and msg needs to be in bytes or atleast mention that if you are assuming so.Shalom
H
13
>>> import hmac
>>> import hashlib
>>> import base64
>>> s = """GET
... webservices.amazon.com
... /onca/xml
... AWSAccessKeyId=00000000000000000000&ItemId=0679722769&Operation=ItemLookup&ResponseGroup=ItemAttributes%2COffers%2CImages%2CReviews&Service=AWSECommerceService&Timestamp=2009-01-01T12%3A00%3A00Z&Version=2009-01-06"""
>>> base64.b64encode(hmac.new("1234567890", msg=s, digestmod=hashlib.sha256).digest())
'Nace+U3Az4OhN7tISqgs1vdLBHBEijWcBeCqL5xN9xg='
Highpowered answered 20/8, 2009 at 16:41 Comment(0)
T
5

From http://docs.python.org/library/hashlib.html#module-hashlib (modified a bit):

import hashlib
secretKey = "1234567890"
m = hashlib.sha256()

# Get string and put into givenString.

m.update(givenString + secretKey)
m.digest()
Taverner answered 20/8, 2009 at 14:27 Comment(1)
You may need to install py25-hashlib. I tried to test this code on Python 2.5.4 (March 5, 2009) but got ImportError: No module named _md5.Taverner
A
3

If you are trying to sign up a user to AWS cognito using Python3, you can use the following code.

#For the SecretHash 
import hmac
import hashlib
import base64   

//Please note that the b in the secretKey and encode('utf-8') are really really important. 
secretKey = b"secret key that you get from Coginito -> User Pool -> General Settings -> App Clients-->Click on Show more details -> App client secret  "
 clientId = "Coginito -> User Pool -> General Settings -> App Clients-->App client id"
 digest = hmac.new(secretKey,
              msg=(user_name + clientId).encode('utf-8'),
              digestmod=hashlib.sha256
             ).digest()
 secrethash = base64.b64encode(digest).decode()

The username user_name in the above is same as the user that you want to register in the cognito

client = boto3.client('cognito-idp', region_name='eu-west-1' )

response = client.sign_up(
                    ClientId='Coginito -> User Pool -> General Settings -> App Clients-->App client id',
                    Username='Username of the person you are planning to register',
                    Password='Password of the person you are planning to register',
                    SecretHash=secrethash,
                    UserAttributes=[
                        {
                            'Name': 'given_name',
                            'Value': given_name
                        },
                        {
                            'Name': 'family_name',
                            'Value': family_name
                        },
                        {
                            'Name': 'email',
                            'Value': user_email
                        }
                    ],
                    ValidationData=[
                        {
                            'Name': 'email',
                            'Value': user_email
                        },
                    ]
Adiabatic answered 2/7, 2019 at 18:10 Comment(0)
S
3

If you have string secret and string token, it may help (I know it may be too late, but just in case it works for someone). All three options worked for me in python 3 -

import hmac
import hashlib
import base64

access_token = 'a'
app_secret = 'b'

access_token = <your token in string format>
app_secret = <your secret access key in string format>

# use any one, all three options work.
# OPTION 1 (it works)
# digest = hmac.new(app_secret.encode('UTF-8'),
#                   access_token.encode('UTF-8'), hashlib.sha256)
# OPTION 2 (it works)
# digest = hmac.new(str.encode(app_secret),
#                   str.encode(access_token), hashlib.sha256)
# OPTION 3 (it works)
digest = hmac.new(bytes(app_secret, 'UTF-8'),
                bytes(access_token, 'UTF-8'), hashlib.sha256)
signature = digest.hexdigest()
print(signature)
Stretcherbearer answered 31/12, 2020 at 6:3 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.