Google-App-Script vs php in encoding base64
Asked Answered
T

1

1

This php code decodes the secret key before hashing with SHA 512

$API_SECRET_KEY="W0+m0Dc9GMN9yDVeq3GMDsJ49WasEhQHkNHNuDw3wNg=";
$BDAPI_SECRET_KEY=base64_decode($API_SECRET_KEY);
$HMAC_SIGN = base64_encode(hash_hmac('sha512',$MESSAGE,$BDAPI_SECRET_KEY,true));
echo $HMAC_SIGN;

BfVNi21gY09c8M18cWBRBgo1W9pAlXM99ZVoF7Kz2ETFnIuvXjj8NRvRgn/GaT/m6YJ8efsr5s9EDbIhznAaag==

I want to replicate this in google app script

var Secret = "W0+m0Dc9GMN9yDVeq3GMDsJ49WasEhQHkNHNuDw3wNg="  
var BDSecret= Utilities.base64Decode(Secret)
var hmac = Utilities.base64Encode(Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, message, BDSecret ));
    Logger.log(hmac)

ew5KhLWSJixn8zw4s6VkpYIwvGBjrmjY3LhNWZr9CVEw6W22LOGg+lVzA3uQgOVyICSCffw2bzTepnBdoYtldw==

If I do not decode the API before hashing they return the same result. But for this particular purpose, the key needs to be decoded. The message variable is just my first name "Parit" in case someone wants to replicate.

Threedimensional answered 13/3, 2018 at 8:58 Comment(7)
are they the same when you log the key after Base64 decoding? could it be a utf8/non-utf8 issue?Homing
echo $BDAPI_SECRET_KEY; return the same as Logger.log(Utilities.newBlob(BDSecret).getDataAsString());Threedimensional
Do you need Utilities.newBlob(BDSecret).getDataAsString() to get BDSecret as a string? if so, shouldn't it be in the computeHmacSignature arguments too (according to doc, key argument is a string)? Another thing you can try is to give a fourth argument to computeHmacSignature to try to specify another charsetHoming
you are right, GAS decode into source octet array while php decode into text (ASCII). Problem is that some source octet are negative, which does not translate to anything in ASCII.Threedimensional
[91, 79, -90, -48, 55, 61, 24, -61, 125, -56, 53, 94, -85, 113, -116, 14, -62, 120, -11, 102, -84, 18, 20, 7, -112, -47, -51, -72, 60, 55, -64, -40]Threedimensional
Did my answer show you the result what you want? Would you please tell me about it? If you have issues for my answer yet, feel free to tell me. I would like to study to solve your issues.Wrap
By recent Google's update, the byte array can be used for Utilities.computeHmacSignature(). So I updated my answer. Could you please confirm it?Wrap
W
2

I thought that Utilities.computeHmacSignature() might not be able to use []byte for the value. So as a workaround, how about using jsSHA? I think that in your case, you can use https://github.com/Caligatio/jsSHA/blob/master/src/sha512.js.

The flow for using jsSHA is as follows.

Flow :

  1. Download sha512.js.
  2. On script editor, create new script as for example, the filename of sha512.js.
    • Copy and paste the script of sha512.js to the created script.
  3. Copy and paste the sample script to Code.gs of the script editor.
  4. Run myFunction() of the sample script.

Sample script :

function myFunction() {
  var message = "Parit";
  var secret = "W0+m0Dc9GMN9yDVeq3GMDsJ49WasEhQHkNHNuDw3wNg=";
  var obj = new jsSHA("SHA-512", "TEXT");
  obj.setHMACKey(secret, "B64");
  obj.update(message);
  Logger.log(obj.getHMAC("B64"))
}

Note :

  • When I tested Parit for message, I got BfVNi21gY09c8M18cWBRBgo1W9pAlXM99ZVoF7Kz2ETFnIuvXjj8NRvRgn/GaT/m6YJ8efsr5s9EDbIhznAaag==.

It this was not useful for you, I'm sorry.

Update :

By the Google's update at June 19, 2018, Utilities.computeHmacSignature() got to be able to use the byte arrays. By this, using only native Google Apps Scvript, the result can be retrieved without using jsSHA. So I would like to update my answer.

Modified script :

function myFunction() {
  var message = "Parit";
  var secret = "W0+m0Dc9GMN9yDVeq3GMDsJ49WasEhQHkNHNuDw3wNg=";

  var value = Utilities.base64Decode(Utilities.base64Encode(message));
  var key = Utilities.base64Decode(secret);
  var out = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512, value, key);
  var res = Utilities.base64Encode(out)
  Logger.log(res)
}

Result :

BfVNi21gY09c8M18cWBRBgo1W9pAlXM99ZVoF7Kz2ETFnIuvXjj8NRvRgn/GaT/m6YJ8efsr5s9EDbIhznAaag==
Wrap answered 13/3, 2018 at 23:16 Comment(3)
Thank you. This solution worked for me. The GAS code (Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512...) does not produce the same signature as a few other libraries I've tried.Unpleasantness
@Unpleasantness Yes. I also had the same situation. So I used this method. I'm glad your issue was solved. Thank you, too.Wrap
@Unpleasantness By recent Google's update, the byte array can be used for Utilities.computeHmacSignature(). So I updated my answer. Could you please confirm it?Wrap

© 2022 - 2024 — McMap. All rights reserved.