-
-
Save craigderington/9cb3ffaf4279af95bebcc0470212f788 to your computer and use it in GitHub Desktop.
import os | |
import hashlib | |
import uuid | |
import hmac | |
from datetime import datetime, timedelta | |
my_api_key = os.urandom(64) | |
def verify(api_key, token, timestamp, signature): | |
hmac_digest = hmac.new(key=api_key, | |
msg="{}{}".format(timestamp, token).encode('utf-8'), | |
digestmod=hashlib.sha1).hexdigest() | |
return hmac.compare_digest(signature, hmac_digest) | |
def main(): | |
token = uuid.uuid4() | |
timestamp = datetime.now().strftime("%Y-%m-%D %H:%M:%S") | |
msg = "{}{}".format(timestamp, token).encode("utf-8") | |
hmac_digest = hmac.new( | |
key=my_api_key, | |
msg=msg, | |
digestmod=hashlib.sha1).hexdigest() | |
# show the message vars | |
print(token, timestamp, hmac_digest) | |
# verify the hash | |
print(verify(my_api_key, token, timestamp, hmac_digest)) | |
if __name__ == "__main__": | |
main() |
Hi There. Sure, happy to help...
To help understand the benefits of Hashed Messaging Authentication (HMAC), let us assume you need to accept a remote webhook POST containing data that you need to verify and then act upon in your backend. The first thing we need to do is make sure the webhook request is from a valid source. We don't want to accept data if we can not verify its origin.
The secret API Key is known to both parties.
The data from the remote webhook (like MailGun) contains a json object consisting of a token, a timestamp and the data. With hmac, we can very simply verify the data is from a valid source by comparing the digital signatures which are created from hashing (SHA1) the concatenated token and timestamp. If the digital signatures match, the request is valid and you can proceed to accept the data in the json and process it in your backend.
Alternatively, your application can encode and send data with hashed messaging by using the exact same method. You just don't need to verify. Use hmac.new() to create the signature to include in your POST request.
Hope that helps explain the code above.
In a real project, I would have a conditional block like:
if verify(api_key, token, timestamp, signature):
# data verified, execute this code...
else:
# data from unknown source, return False and exit
Take a look at this Flask project to see how I use hmac to accept and process webhooks from a 3rd party API.
https://github.com/craigderington/flask-rest-mailgun-webhooks
Good luck!
Hi, i am a newly working on HMAC and i was refering to your code it really super can you explain the code a bit.
it will really helpfull.
thank you