Skip to content
Advertisement

HMAC SHA-512 hashing function equivalent in node.js

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: ‘TestMessage’

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?

Advertisement

Answer

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.

User contributions licensed under: CC BY-SA
2 People found this is helpful
Advertisement