37

I am taking message and key from this URL

import hmac
import hashlib
import base64
my = "/api/embedded_dashboard?data=%7B%22dashboard%22%3A7863%2C%22embed%22%3A%22v2%22%2C%22filters%22%3A%5B%7B%22name%22%3A%22Filter1%22%2C%22value%22%3A%22value1%22%7D%2C%7B%22name%22%3A%22Filter2%22%2C%22value%22%3A%221234%22%7D%5D%7D"
key = "e179017a-62b0-4996-8a38-e91aa9f1"
print(hashlib.sha256(my + key).hexdigest())

I am getting this result:

2df1d58a56198b2a9267a9955c31291cd454bdb3089a7c42f5d439bbacfb3b88

Expecting result:

adcb671e8e24572464c31e8f9ffc5f638ab302a0b673f72554d3cff96a692740
2
  • You used this for periscope-data embed api right? Commented Jun 16, 2020 at 10:49
  • Similar question but sufficient answers here I believe: stackoverflow.com/questions/53910845/… Commented May 14, 2022 at 5:26

6 Answers 6

48

You are not making use of hmac at all in your code.

Typical way to use hmac, construct an HMAC object from your key, message and identify the hashing algorithm by passing in its constructor:

h = hmac.new( key, my, hashlib.sha256 )
print( h.hexdigest() )

That should output

adcb671e8e24572464c31e8f9ffc5f638ab302a0b673f72554d3cff96a692740

for your example data.

Sign up to request clarification or add additional context in comments.

1 Comment

h = hmac.new(base64.b32encode(key), my, hashlibsha256) to make sure that key is always valid bas32 encoded string.
47

For later versions of python, you need a mix of all of the other answers to get the OPs output. The hmac.new function wants the key argument to be of type bytes or bytearray, so running the code in Neil Slater's answer would produce the following error:

TypeError: key: expected bytes or bytearray, but got 'str'

Even if the key argument were fixed, the hmac.new function would then complain about the my string with the following error:

TypeError: Unicode-objects must be encoded before hashing

To fix both of these, the encode method from Wilson Wu's answer is used to convert the variables into the correct types.

import hashlib
import hmac

# Define my and key as per question
my = "/api/embedded_dashboard?data=%7B%22dashboard%22%3A7863%2C%22embed%22%3A%22v2%22%2C%22filters%22%3A%5B%7B%22name%22%3A%22Filter1%22%2C%22value%22%3A%22value1%22%7D%2C%7B%22name%22%3A%22Filter2%22%2C%22value%22%3A%221234%22%7D%5D%7D"
key = "e179017a-62b0-4996-8a38-e91aa9f1"

# Encode as per other answers
byte_key = key.encode("UTF-8")
message = my.encode()

# Now use the hmac.new function and the hexdigest method
h = hmac.new(byte_key, message, hashlib.sha256).hexdigest()

# Print the output
print(h)

The output that this prints is

adcb671e8e24572464c31e8f9ffc5f638ab302a0b673f72554d3cff96a692740

exactly as the OP expected.

2 Comments

Thank you for the compilation. I tested this with Python 3.11.5 and it works fine. I think a more specific wording instead of later versions of Python would make this answer even better. In my opinion, it would also be better to consistently use either bytes() or str.encode(). I would lean towards encode here, but it might be better to read some arguments from Python professionals.
@Wolf -- totally agree with both comments! I've updated the answer to use str.encode() consistently, but I don't actually know which version this is correct from hence the ambiguity (I would prefer to put an actual version)
8

Some code for you, easy to use:

import hmac
import hashlib
import binascii

def create_sha256_signature(key, message):
    byte_key = binascii.unhexlify(key)
    message = message.encode()
    return hmac.new(byte_key, message, hashlib.sha256).hexdigest().upper()

create_sha256_signature("E49756B4C8FAB4E48222A3E7F3B97CC3", "TEST STRING")

Comments

1

A note to Wilson WU's answer, if both the key and messages are hex, the returned value is wrong, just change below line of code to fix that ;

message = message.encode() ---> message = message.binascii.unhexlify(message)

1 Comment

also is only the key is in hex you need unhexify. thanks for this. spend days on it.
1

It may be too late. Yet, posting what worked for me just in case it works for someone else -

import hmac
import hashlib
import base64

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)

Comments

0

In case hash method is not directly accessibly from hashlib module, for example sm3, using the following way to work around

import hmac
import hashlib

h = hmac.new(b'key', msg=b'data', digestmod='sha256')
print(h.hexdigest())

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.