Recreating a CryptoJS Hmac using python

跟風遠走 提交于 2021-02-11 13:55:55

问题


The scenario is that I have a JS script that creates a HMAC for a user provided input and I want to compute the same HMAC for the same input using python. To make things clearer, consider the following JS and Python code snippets.

Javascript

<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/crypto-js.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/hmac-sha256.min.js"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/crypto-js/3.1.9-1/enc-base64.min.js"></script>

<script>
    var secretAccessKey = "bAvW5O18eSrxke4I7eFcrnrDJkN+wKQmx9aSHuMZQ0w=";
    var stringtoSign = "Test";

    // Generate HMAC SHA256 signature
    var secretAccessKeyBase64 = CryptoJS.enc.Base64.parse(secretAccessKey);
    var hash = CryptoJS.HmacSHA256(stringtoSign, secretAccessKeyBase64);
    var signature = CryptoJS.enc.Base64.stringify(hash);
</script>

Python

stringToSign = "Test"
secretAccessKey = "bAvW5O18eSrxke4I7eFcrnrDJkN+wKQmx9aSHuMZQ0w="

secretAccessKeyBase64 = base64.b64decode(secretAccessKey).hex()
keyBytes = bytes(secretAccessKeyBase64, 'utf-8')
stringToSignBytes = bytes(stringToSign, 'utf-8')
signatureHash = hmac.new(keyBytes, stringToSignBytes, digestmod=hashlib.sha256).digest()
signature = base64.b64encode(signatureHash)
print(signature)

The Javascript code gives me b+1wRzDODA85vyDZkXByPIKO5qmnjCRNF5gZFi33/Ic=, while python gives me the value b'SsZ4bcYe3op1nGU6bySzlSc9kgg9Kgp37qzF15s2zNc='

Why is my python code generating a different HMAC for (seemingly) identical inputs that was provided to the JS script? Is there anyway to obtain the HMAC value outputted by the JS code using python?


回答1:


You are using a Base64 encoded value as secret in Javascript, whereas in Python you use the plain text secret.

<script>
    var secretAccessKeyBase64 = "secret";
    var hash = CryptoJS.HmacSHA256("Message", secretAccessKeyBase64);
    var hashInBase64 = CryptoJS.enc.Base64.stringify(hash);
    document.write(hashInBase64);
</script>

This prints out the same value as the Python code:

qnR8UCqJggD55PohusaBNviGoOJ67HC6Btry4qXLVZc=

Edit:

base64 returns a byte-object there is no need to convert it to hex():

stringToSign = "Test"
secretAccessKey = "bAvW5O18eSrxke4I7eFcrnrDJkN+wKQmx9aSHuMZQ0w="

secretAccessKeyBase64 = base64.b64decode(secretAccessKey)
keyBytes = secretAccessKeyBase64
stringToSignBytes = bytes(stringToSign, 'utf-8')

signatureHash = hmac.new(keyBytes, stringToSignBytes, digestmod=hashlib.sha256).digest()
signature = base64.b64encode(signatureHash)
print(signature)

Prints correctly:

b'b+1wRzDODA85vyDZkXByPIKO5qmnjCRNF5gZFi33/Ic='


来源:https://stackoverflow.com/questions/54317579/recreating-a-cryptojs-hmac-using-python

易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!