如何使用十六进制密钥在 Google Apps 脚本中正确计算 HMAC

How to correctly calculate HMAC in Google Apps Script using hexadecimal key

我正在尝试使用需要 HMAC 进行身份验证的 API。 我能够使用 PHP(使用供应商的说明)生成并使用正确的密钥,但现在我需要在 Google Apps 脚本中执行相同的操作,但我失败了...

供应商提供的 API 密钥是 C77C96EEF6F6995B,其中包含 8 字节十六进制的信息。

下面是我的工作 PHP 脚本:

<?php
$klucz = chr(hexdec('C7')).chr(hexdec('7C')).chr(hexdec('96')).chr(hexdec('EE')).chr(hexdec('F6')).chr(hexdec('F6')).chr(hexdec('99')).chr(hexdec('5B'));
$url = "https://www.ifirma.pl/iapi/abonent/miesiacksiegowy.json";
$nazwaUsera = "WIJARAY978@NIEKIE.COM";
$nazwaKlucza = "abonent";
$hashWiadomosci = hash_hmac("sha1",$url.$nazwaUsera.$nazwaKlucza, $klucz);
echo $hashWiadomosci;
?>

它生成一个散列:9b5f9bb41ac30b9c55b10f3cecdd6e12e852f274 当我与邮递员一起使用它时,调用 API 工作正常。 问题是当我试图以类似的方式在 Google 应用程序脚本中复制它时:

function bytesToHex(data) {
    return data.map(function(e) {
        var v = (e < 0 ? e + 256 : e).toString(16);
        return v.length == 1 ? "0" + v : v;
    }).join("");
}

function callNumbers() {
  var klucz = String.fromCharCode(parseInt("C7",16))+String.fromCharCode(parseInt("7C",16))+String.fromCharCode(parseInt("96",16))+String.fromCharCode(parseInt("EE",16))+String.fromCharCode(parseInt("F6",16))+String.fromCharCode(parseInt("F6",16))+String.fromCharCode(parseInt("99",16))+String.fromCharCode(parseInt("5B",16)); 

  var user = "WIJARAY978@NIEKIE.COM"
  var url = "https://www.ifirma.pl/iapi/abonent/miesiacksiegowy.json";
  var wiadomosc = url+user+"abonent";

  var hmac = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, wiadomosc, klucz);
  
  hmac=bytesToHex(hmac)
  Logger.log(hmac);
}

这个 returns 我完全不同的计算哈希:6f50edae11b1f7f5b8488a99c4df3e797662c739

请帮我调试一下

顺便说一句。代码中的凭据是虚拟帐户的工作凭据。

在您的脚本中,如何将 $klucz = chr(hexdec('C7')).chr(hexdec('7C')).chr(hexdec('96')).chr(hexdec('EE')).chr(hexdec('F6')).chr(hexdec('F6')).chr(hexdec('99')).chr(hexdec('5B')); 的十六进制值转换为 Google Apps 脚本中的字节数组?在 Google Apps Script,我认为使用字节数组可能比使用二进制数据更合适。

当这反映在您的脚本中时,它将变成如下。

修改后的脚本:

本次修改,函数callNumbers()被修改

function callNumbers() {
  var hex = "C77C96EEF6F6995B";
  var klucz = hex.match(/.{2}/g).map(e => parseInt(e[0], 16).toString(2).length == 4 ? parseInt(e, 16) - 256: parseInt(e, 16));

  var user = "WIJARAY978@NIEKIE.COM"
  var url = "https://www.ifirma.pl/iapi/abonent/miesiacksiegowy.json";
  var wiadomosc = url+user+"abonent";

  var hmac = Utilities.computeHmacSignature(Utilities.MacAlgorithm.HMAC_SHA_1, Utilities.newBlob(wiadomosc).getBytes(), klucz);
  
  hmac=bytesToHex(hmac)
  Logger.log(hmac);
}
  • 通过将HEX值转换为字节数组,Utilities.computeHmacSignature的参数也需要转换为字节数组。
  • 当此脚本为运行时,得到9b5f9bb41ac30b9c55b10f3cecdd6e12e852f274。该值与您的 PHP 脚本的值相同。
  • 当然也可以用var klucz = ['C7', '7C', '96', 'EE', 'F6', 'F6', '99', '5B'].map(e => parseInt(e[0], 16).toString(2).length == 4 ? parseInt(e, 16) - 256 : parseInt(e, 16));

参考: