Calculating a SHA hash with a string + secret key in python

Question:

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'

Asked By: mymmaster

||

Answers:

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()
Answered By: Andrew Keeton
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='
Answered By: SilentGhost
>>> 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='
Answered By: Filip Salomonsson
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.

Answered By: George Campbell

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
                        },
                    ]
Answered By: Haris Np

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)
Answered By: Sujoy
Categories: questions Tags: , ,
Answers are sorted by their score. The answer accepted by the question owner as the best is marked with
at the top-right corner.