【问题标题】:Google-App-Script vs php in encoding base64编码base64的Google-App-Script vs php
【发布时间】:2018-03-13 08:58:47
【问题描述】:

此 php 代码在使用 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==

我想在谷歌应用脚​​本中复制这个

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==

如果我在散列之前不解码 API,它们会返回相同的结果。但是为了这个特定的目的,需要对密钥进行解码。 message 变量只是我的名字“Parit”,以防有人想要复制。

【问题讨论】:

  • Base64解码后记录密钥时它们是否相同?会不会是 utf8/非 utf8 问题?
  • 回显 $BDAPI_SECRET_KEY;返回相同的 Logger.log(Utilities.newBlob(BDSecret).getDataAsString());
  • 你需要Utilities.newBlob(BDSecret).getDataAsString() 来获取BDSecret 作为字符串吗?如果是这样,它不应该在computeHmacSignature 参数中(根据文档,关键参数是一个字符串)吗?您可以尝试的另一件事是给computeHmacSignature 提供第四个参数以尝试指定另一个字符集
  • 你是对的,GAS 解码为源字节数组,而 php 解码为文本(ASCII)。问题是某些源八位字节是负数,不能转换为 ASCII 中的任何内容。
  • [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]

标签: php google-apps-script base64 encode hmac


【解决方案1】:

我认为Utilities.computeHmacSignature() 可能无法使用 []byte 作为值。那么作为一种解决方法,使用 jsSHA 怎么样?我认为在你的情况下,你可以使用https://github.com/Caligatio/jsSHA/blob/master/src/sha512.js

jsSHA的使用流程如下。

流程:

  1. 下载 sha512.js。
  2. 在脚本编辑器上,创建新脚本,例如sha512.js 的文件名。
    • 将 sha512.js 的脚本复制并粘贴到创建的脚本中。
  3. 将示例脚本复制并粘贴到脚本编辑器的Code.gs
  4. 运行示例脚本的myFunction()

示例脚本:

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"))
}

注意:

  • 当我为message 测试Parit 时,我得到了BfVNi21gY09c8M18cWBRBgo1W9pAlXM99ZVoF7Kz2ETFnIuvXjj8NRvRgn/GaT/m6YJ8efsr5s9EDbIhznAaag==

这对你没有用,对不起。

更新:

By the Google's update at June 19, 2018, Utilities.computeHmacSignature() 必须能够使用字节数组。这样,仅使用本机 Google Apps Scvript,就可以在不使用 jsSHA 的情况下检索结果。所以我想更新我的答案。

修改后的脚本:

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)
}

结果:

BfVNi21gY09c8M18cWBRBgo1W9pAlXM99ZVoF7Kz2ETFnIuvXjj8NRvRgn/GaT/m6YJ8efsr5s9EDbIhznAaag==

【讨论】:

  • 谢谢。这个解决方案对我有用。 GAS 代码 (Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_512...) 不会产生与我尝试过的其他几个库相同的签名。
  • @pomo 是的。我也有同样的情况。所以我用了这个方法。我很高兴你的问题得到了解决。也谢谢你。
  • @pomo 根据最近谷歌的更新,字节数组可以用于Utilities.computeHmacSignature()。所以我更新了我的答案。你能确认一下吗?
猜你喜欢
  • 2014-04-04
  • 2015-04-18
  • 2013-01-13
  • 2012-05-03
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2017-11-24
  • 2017-08-13
相关资源
最近更新 更多