18

I am connecting to the Amazon Product Advertising API, and to sign my request I need to base64-encode the raw binary output of an HMAC-SHA256 hash.

In the PHP documentation for hash_hmac, the fourth parameter bool $raw_output controls whether the output is raw binary data (true) or lowercase hexits (false). My program works in PHP by simply setting that parameter to true.

However, I am now trying to port this over to Javascript. I tried using the CryptoJS.HmacSHA256() function, but it seems to be returning the lowercase hexits. How can I convert this to binary?

I have tried the following according to the CryptoJS documentation, but both outputs are identical:

var hash = CryptoJS.HmacSHA256("hello", "key");
console.log(hash.toString());
console.log(hash.toString(CryptoJS.enc.Base64));

6 Answers 6

22

This is explained in their documentation. Try this:

var hash = CryptoJS.HmacSHA256("Message", "Secret Passphrase");

var base64 = hash.toString(CryptoJS.enc.Base64);

You need to include http://crypto-js.googlecode.com/svn/tags/3.0.2/build/components/enc-base64-min.js for this. If you didn't include this, CryptoJS.enc.Base64 will be undefined and fallback to the default.

Working demo: http://jsfiddle.net/ak5Qm/

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

10 Comments

I have already tried that, it doesn't seem to work. Please see my revised question for a better explanation.
@Kevin did you include the base64-min.js? Since it works fine here: jsfiddle.net/ak5Qm
@Kevin if you use google chrome, press ctrl+shift+j when your page loads and see if there are errors. You can also simply write CryptoJS.enc.Base64 in your console to see if it's undefined
It turns out I had my scripts included in the wrong order: enc-base64 THEN hmac-sha256, rather than vice versa. Switching this order solved the problem. Thanks again!
@Esailija I think the fiddle on longer works. Looks like Google moved those scripts
|
10

PHP:

base64_encode(hash_hmac('sha256', $value, $key, true));

Nodejs equivalent:

const crypto = require('crypto');
let token = crypto.createHmac("sha256", key).update(value).digest().toString('base64');

Comments

4

php code

echo base64_encode(hash_hmac('SHA1', 'shanghai', '0', true).'beijing');

php output

xvBv49PpaYvXAIfy3iOSDWNQj89iZWlqaW5n

node code

var crypto = require('crypto');
var buf1 = crypto.createHmac("sha1", "0").update("shanghai").digest();
var buf2 = Buffer.from('beijing');
console.log(Buffer.concat([buf1, buf2]).toString('base64'));    

node output

xvBv49PpaYvXAIfy3iOSDWNQj89iZWlqaW5n

1 Comment

Your code is not clear, what is the key and what is the value?
1

For the web browser:

async hmac_sha1 (str, secret) {
  let enc = new TextEncoder("utf-8");
  let key = await window.crypto.subtle.importKey(
    "raw",
    enc.encode(secret),
    {
      name: "HMAC",
      hash: {name: "SHA-1"}
    },
    false,
    ["sign", "verify"]
  );
  let signature = await window.crypto.subtle.sign(
    "HMAC",
    key,
    enc.encode(str)
  );
  let b = new Uint8Array(signature);
  return Array.prototype.map.call(b, x => x.toString(16).padStart(2, '0')).join("");
}

Comments

0

You can also use this npm package to do the same in Javascript.

var jsSHA = require('jssha');

hmac_sha1(string, key){
    let shaObj = new jsSHA("SHA-1", "TEXT");
    shaObj.setHMACKey(key, "TEXT");
    shaObj.update(string);
    let hmac = shaObj.getHMAC("B64");
    return hmac;
};

1 Comment

You can put your private key's also into my public library !
0

This worked for me :

var CryptoJS = require("crypto-js");
const raw_signature = hmacSHA1(baseString, signingKey);
const signature = raw_signature.toString(CryptoJS.enc.Base64);

It's giving the exact same result as, in PHP, :

$rawSignature = hash_hmac("sha1", $baseString, $signingKey, true);
$signature    = base64_encode($rawSignature);

Comments

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.