Can you anybody explain me a difference between creating HmacSha512 signature using Crypto module of Node.JS and Google Apps Script?
Code 1 - Node.JS
var secret = "my secret";
var message = "message";
var crypto = require("crypto");
var hmac = new crypto.createHmac("sha512", secret);
var signature = hmac.update(message).digest("base64");
console.log(signature);
Code 1 - Google Apps Script
var secret = "my secret";
var message = "message";
var signature = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, message, secret));
Logger.log(signature);
Both of codes generate identical signature:
g4fZkM2XGNjhti9Wah3TU2/rvmxbL3nk4F3ZLljpED23oQ7Y7dtVmVKprQKuzyt0B4Spo214isWCvnoXXVTS8g==
But the problem comes when we have the secret in the form of base64 encoded key. So, first step we have to do is prepare the secret. Let's modify the code:
Code 2 - Node.JS
var key = "JOLDQW5wVIdwvHbhSDCktxhfwpgtxlAH+DG5EPoeDT8aPGSDYYh5U6QjbASUhvztjGPgA/Ue2x8QKwUklX7+Xw==";
var secret = new Buffer(key, "base64");
var message = "message";
var crypto = require("crypto");
var hmac = new crypto.createHmac("sha512", secret);
var signature = hmac.update(message).digest("base64");
console.log(signature);
The result:
GELSKf33zit7nIfjj8XH3wZIga/CSYuCU5oTGysqOg6C/wFggunw59wzc7Mr95XW/gZ8putB67AADqnP0gLdiw==
Code 2 - Google Apps Script
var key = "JOLDQW5wVIdwvHbhSDCktxhfwpgtxlAH+DG5EPoeDT8aPGSDYYh5U6QjbASUhvztjGPgA/Ue2x8QKwUklX7+Xw==";
var message = "message";
var secret = Utilities.base64Decode(key);
var signature = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, message, secret));
Logger.log(signature);
The result:
l11xAQ5C5ARx/r/pbNYpMKCqWOwIaxFTkfS9OXCwfUxv33y3gU/sL2vHueOxpkCKmF+lxIcFMYblwrvfWaTZkg==
The difference is probably in processing/decoding the key (Buffer vs. Utilities.base64Decode. The Node.js version is the right (it's verified against to server-side).
How to correctly decode and use the key using Google Apps Script?
Utilities.base64Decode() returns a byte array not a string. You can create a blob from the byte array and then get it as a string restoring the original encoded string.
var secret = Utilities.base64Decode(key);
secret = Utilities.newBlob(secret).getDataAsString();
Try this example. I replaced your key with a new base64 encoded string and converted b64-decoded outputs to strings:
In node:
var key = "VEhJUyBJUyBBIFNUUklORw==";
//var key = "JOLDQW5wVIdwvHbhSDCktxhfwpgtxlAH+DG5EPoeDT8aPGSDYYh5U6QjbASUhvztjGPgA/Ue2x8QKwUklX7+Xw==";
var secret = new Buffer(key, "base64").toString();
var message = "message";
var crypto = require("crypto");
var hmac = new crypto.createHmac("sha512", secret);
var signature = hmac.update(message).digest("base64");
console.log(signature);
In GAS:
//var key = "JOLDQW5wVIdwvHbhSDCktxhfwpgtxlAH+DG5EPoeDT8aPGSDYYh5U6QjbASUhvztjGPgA/Ue2x8QKwUklX7+Xw==";
var key = "VEhJUyBJUyBBIFNUUklORw=="
var message = "message";
var secret = Utilities.base64Decode(key);
secret = Utilities.newBlob(secret).getDataAsString();
var hmac = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, message, secret);
var signature = Utilities.base64Encode(hmac);
Logger.log(signature);
both return the signature:
a9Jk2YQsKC164zEUoVChIpyfnEUZLj+Sj1mCAqs+jhDFvOliTupIfV+D6CNtaQGhQvAO40FZLhvYGubt1R5jQA==
But if I put your key back in the signatures again stop matching.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With