2

I currently have this snippet in Python -

import base64 import hashlib import hmac def hash_hmac(self, key, data): res = hmac.new(base64.b64decode(key), data.encode(), hashlib.sha512).digest() return res 

I am trying to replicate it in Node.js, but having difficulty getting the correct hash.

const crypto = require('crypto') const hashHmac = (key, message) => { return crypto.createHmac('sha512', Buffer.from(key, 'base64').toString('utf-8')) .update(message) .digest() .toString('base64') } 

Test case: Key: '7pgj8Dm6' Message: 'Test\0Message'

With the python snippet, the hash is

69H45OZkKcmR9LOszbajUUPGkGT8IqasGPAWqW/1stGC2Mex2qhIB6aDbuoy7eGfMsaZiU8Y0lO3mQxlsWNPrw== 

With the js snippet, the hash is

OhaJU9IibhhjIjz3R7FmodgOBUPjwhndXX8gn0r2rRzjQvCJl4T40rHXKw3o6Y2JQ5fVHTeStu8K1DRMWxMGBg== 

Am I going wrong with the base64 encoding?

3
  • 1
    In the NodeJS code replace Buffer.from(key, 'base64').toString('utf-8') with Buffer.from(key, 'base64'). The UTF-8 decoding corrupts the data. Commented Jul 2, 2021 at 6:15
  • Awesome it worked!, can you answer it so I can accept it :) Commented Jul 2, 2021 at 7:03
  • Sure. I posted my comment as an answer. Commented Jul 2, 2021 at 7:47

2 Answers 2

3

In the NodeJS code, the key is first Base64 decoded and then UTF-8 decoded. Since the key contains byte sequences that are not defined by UTF-8, it is thereby damaged.

Arbitrary binary data, such as ciphertexts, hashes, or keys (at least if randomly generated), must be stored in binary, or a binary-to-text encoding like Base64 must be used (and not a character set encoding like UTF-8) if they are to be converted to a string, see also here.

In the posted example, converting the buffer to a string is not necessary at all. The key can simply be passed directly as a buffer, s. crypto.createHmac(), i.e. as follows:

var hmac = crypto.createHmac('sha512', Buffer.from(key, 'base64')); 

With this, the NodeJS code returns the same result as the Python code.

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

Comments

0

If you installed NodeJs:

 echo "console.log(require('crypto').createHmac('sha512', 'nonbase64key').update('password').digest('hex'))" | node 

it's equivalent in python is:

python3 -c 'import hashlib;import base64;import hmac;print(hmac.new(b"nonbase64key", "password".encode(), hashlib.sha512).hexdigest())' 

And the equivalent pure shell command is:

echo -n "password" | openssl sha512 -hmac "nonbase64key" 

Comments

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.