Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Generate HMAC Sha256 in python 3

I write code to verify an HMAC Auth incoming POST request with JSON to our API. The HMAC I received is OD5ZxL4tdGgWr78e9vO3cYrjuOFT8WOrTbTIuuIH1PQ=

When I try to generate it by my self using Python, it is always different.

Here is the JSON request I received:

{
    "shipper_id": 4841,
    "status": "Cancelled",
    "shipper_ref_no": "",
    "tracking_ref_no": "",
    "shipper_order_ref_no": "",
    "timestamp": "2018-05-23T15:13:28+0800",
    "id": "61185ecf-3484-4985-b625-ffe30ba36e28",
    "previous_status": "Pending Pickup",
    "tracking_id": "NVSGBHINK000000001"
}

And the client secret is 817a3723917f4c7fac24b1f1b324bbab.

The HMAC secret I received is OD5ZxL4tdGgWr78e9vO3cYrjuOFT8WOrTbTIuuIH1PQ=.

Here is the code when I write it in PHP:

<?php
define('CLIENT_SECRET', 'my_shared_secret');
function verify_webhook($data, $hmac_header){
    $calculated_hmac = base64_encode(hash_hmac('sha256', $data, CLIENT_SECRET, true));
    return ($hmac_header == $calculated_hmac);
}  
$hmac_header = $_SERVER['X-NINJAVAN-HMAC-SHA256'];
$data = file_get_contents('php://input');  
$verified = verify_webhook($data, $hmac_header);
error_log('Webhook verified: '.var_export($verified, true)); //check error.log to see result
?>

But I have no idea how to do it in Python 3.

like image 1000
Larissa Hameru Avatar asked Oct 17 '25 15:10

Larissa Hameru


2 Answers

In Python 3 you basically want something like the following, taken from how you handle GitHub webhook requests.

import hashlib
import hmac

secret = 'CLIENT_SECRET'
data = rsp.content # assumes you're using requests for data/sig
signature = rsp.headers['X-Something-Signature']
signature_computed = 'sha1=' + hmac.new(
    key=secret.encode('utf-8'),
    msg=data.encode('utf-8'),
    digestmod=hashlib.sha1
).hexdigest()
if not hmac.compare_digest(signature, signature_computed):
    log("Invalid payload")
like image 120
dmulter Avatar answered Oct 20 '25 13:10

dmulter


If you want to recreate the hashing code from PHP to Python do it thusly:

def create_signature(key, data):
    sig_hash =  hmac.new(key.encode('utf8'), data.encode('utf8'), hashlib.sha256).digest()
    base64_message = base64.b64encode(sig_hash).decode()
    return base64_message

This will create the signature that should match what your PHP code is creating. Just compare the signature to what is sent in the header.

like image 31
earl3s Avatar answered Oct 20 '25 11:10

earl3s