5

I'm running node.js and php on windows and I use the included crypto module in node.js.

Php script:

hash_hmac("sha256", "foo", "bar", true) // the true enables binary output

outputs:

¶y3!è¬╝♂ï►ó│Ñ├Fä╚┘CA╝±G6▄rp¸t↑Q

Node.js script:

crypto.createHmac("sha256", "bar").update("foo").digest("binary");

outputs:

¶y3!?ª¼♂?►¢³¥ÃF?ÈÙCA¼ñG6Ürp÷t↑Q

I also wonder why some digits are the same but some others not.


I also tried getting the hex instead of the binary result, both of them output the same.

hash_hmac("sha256", "foo", "bar", false); // false outputs hex data
crypto.createHmac("sha256", "bar").update("foo").digest("hex"); // notice "hex"

This was not a solution because I failed to convert the hex data to binary:

var hmac = crypto.createHmac("sha256", "bar").update("foo").digest("hex");
var binary = new Buffer(hmac, "hex");

The variable binary outputs:

¶y3!???♂?►????F???CA??G6?rp?t↑Q

2
  • 2
    Anytime you simply convert between binary data and a string of characters, you're utilizing a character encoding. The actual binary data is the same between the two, verified by the hexidecimal output, but the character encoding each are using to represent them when printed isn't. PHP, I'd guess, is assuming ISO-8859-1 while Node's Buffers will use UTF-8. Commented Mar 3, 2015 at 19:57
  • @JonathanLonowski Anyway to make them the same? Commented Apr 28, 2016 at 20:13

2 Answers 2

3

I came across the same problem when implementing a node js solution for OTP simplepay.

PHP Code:

base64_encode(hash_hmac('SHA384', $text, trim($key), true));

JS CODE:

function get_hash(key, text) {
    const crypto = require("crypto");
    const algorithm = "sha384";

    var hmac = crypto.createHmac(algorithm, key).update(text);
    return hmac.digest().toString('base64');
}

So both logged out / echoed - give the same result. In your case, the binary output thus would be:

crypto.createHmac("sha256", "bar").update("foo").digest().toString('binary');

However, keep in mind that logging and echoing a binary string will give a slightly different view due to character encoding. You can see the same, but also different characters.

PHP echo

,cAW'B��o��傱�@�Vlάf�R@y�,?0�^1=Y�����u2

and

NODE console.log

,cAW'BÛåoº°å±¹@VlάfÞ꧸§u2

Are actually the same, they just look different. see this github issue and addaleax's comment

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

Comments

0
calculateHmac(payload) {
    const hmac = crypto.createHmac('sha256', KEY);
    hmac.update(Buffer.from(payload).toString());
    let bin = hmac.digest();
    return Buffer.from(bin).toString('base64');
}

1 Comment

Please don't post only code as answer, but also provide an explanation what your code does and how it solves the problem of the question. Answers with an explanation are usually more helpful and of better quality, and are more likely to attract upvotes.

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.