5

My NodeJS & Python scripts don't return the same hash, what could cause this issue?

Node.js

const { createHmac } = require("crypto");
var message = 'v1:1583197109:'
var key = 'Asjei8578FHasdjF85Hfjkasi875AsjdiAas_CwueKL='
const digest = Buffer.from(key, "base64");
const hash = createHmac("sha256", digest)
  .update(message)
  .digest("hex");

console.log(hash)
> 7655b4f816dc7725fb4507a20f2b97823979ea00b121c84b76924fea167dcaf7

Python3

message = 'v1:1583197109:'
key = 'Asjei8578FHasdjF85Hfjkasi875AsjdiAas_CwueKL=' + '=' #add a "=" to avoid incorrect padding
digest = base64.b64decode(key.encode('utf-8'))
hash_ = hmac.new(digest, message.encode('utf-8'), hashlib.sha256)
hash_result = hash_.hexdigest()
print(hash_result)
> c762b612d7c56d3f9c95052181969b42c604c2d41b7ce5fc7f5a06457e312d5b

I guess it could be the extra = to avoid the incorrect padding but my key ends with a single =.

2
  • 2
    Are you sure you posted correct code? Python example gives another different hash for me... Commented Mar 3, 2020 at 10:50
  • I guess it could be the extra = - firstly, don't guess - test. And I tested it and it changes nothing (if the key encoding is present - without it the padding is needed). Commented Mar 3, 2020 at 10:56

1 Answer 1

4

Node.js Buffer.from(..., 'base64') can consume the input in the "urlsafe" base64 (https://nodejs.org/api/buffer.html#buffer_buffers_and_character_encodings), and _ is not a valid Base64 character for python, while it is for node.

Adding altchars that correspond to the "urlsafe" version of Base64 to python code yields equal hashes.

const { createHmac } = require("crypto");
var message = 'v1:1583197109:'
var key = 'Asjei8578FHasdjF85Hfjkasi875AsjdiAas_CwueKL='

const digest = Buffer.from(key, "base64");
const hash = createHmac("sha256", digest)
  .update(message)
  .digest("hex");

console.log(hash) // 7655b4f816dc7725fb4507a20f2b97823979ea00b121c84b76924fea167dcaf7
message = 'v1:1583197109:'
key = 'Asjei8578FHasdjF85Hfjkasi875AsjdiAas_CwueKL=' + '=' #add a "=" to avoid incorrect padding
digest = base64.b64decode(key.encode('utf-8'), altchars='-_')
hash_ = hmac.new(digest, message.encode('utf-8'), hashlib.sha256)
hash_result = hash_.hexdigest()
print(hash_result) # 7655b4f816dc7725fb4507a20f2b97823979ea00b121c84b76924fea167dcaf7

Also, python's b64decode has validate kwarg, which would check the input string and "fail loud" instead of ignoring incorrect characters

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

1 Comment

According to the documentation, the length of altchars should be at least 2.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.