goog.cryp.Hmac не может воспроизвести результат из крипты с узла js - PullRequest
1 голос
/ 10 октября 2019

Я пытаюсь воспроизвести подпись HMAC, описанную здесь .

В примере используется crypt из nodejs, однако в моем случае мне нужно использовать Google Closureбиблиотека. Поэтому я попытался воспроизвести подпись HMAC с помощью библиотеки goog.crypt.Hmac.

Ниже приведен мой экспериментальный код.

let crypto = require('crypto');
require("google-closure-library");

goog.require("goog.crypt.Hmac");
goog.require("goog.crypt");
goog.require('goog.crypt.Sha1');

function forceUnicodeEncoding(string) {
    return decodeURIComponent(encodeURIComponent(string));
}

function nodejs_crypto(string_to_sign, secret) {
    signature = crypto.createHmac('sha1', secret)
        .update(forceUnicodeEncoding(string_to_sign))
        .digest('base64')
        .trim();
    return signature
}

function goog_crypto(string_to_sign, secret) {
    const hmac = new goog.crypt.Hmac(new goog.crypt.Sha1(), goog.crypt.stringToByteArray(secret));
    const hash = hmac.getHmac(forceUnicodeEncoding(string_to_sign));
    return hash.toString()
}

const string_to_sign = "message";
const secret = "secret";
const sig1 = nodejs_crypto(string_to_sign, secret);
const sig2 = goog_crypto(string_to_sign, secret);

console.log(sig1);
// DK9kn+7klT2Hv5A6wRdsReAo3xY=

console.log(sig2);
// 12,175,100,159,238,228,149,61,135,191,144,58,193,23,108,69,224,40,223,22

Я не могу найти в Интернете примеров для goog.crypt.Hmac.

Вот мои проблемы:

  1. Я не являюсьуверен, что goog_crypto реализован правильно.
  2. почему hash.String() возвращает объект, похожий на массив?
  3. как я могу преобразовать хэш hmac в строку base64 с помощью библиотеки закрытия.

1 Ответ

1 голос
/ 10 октября 2019
  1. Ваша функция goog_crypto выглядит правильно, поскольку результат идентичен, хотя представлен в виде base64 и массива целых чисел (байтов)
  2. Возвращаемое значение getHmac, т.е. hash в вашем коде, является массивом целых чисел - как здесь задокументировано ... и array.toString() очень похоже на array.join()
  3. , если вы хотите, чтобы ваша функция goog_crypto возвращала base64, используйте nodejs BuffertoString для выполнения тяжелой работы за вас

т.е.

function goog_crypto(string_to_sign, secret) {
    const hmac = new goog.crypt.Hmac(new goog.crypt.Sha1(), goog.crypt.stringToByteArray(secret));
    const hash = hmac.getHmac(forceUnicodeEncoding(string_to_sign));
    return Buffer.from(hash).toString('base64');
}

Так как hash является массивом Numbers, Buffer.from(hash) создает буфер из чисел в hash - buffer.toString('base64') возвращает данные буфера в кодировке в base64


Относительно пункта 1: доказать, что результаты, которые вы получаете в своем коде, совпадают

const sig1 = "DK9kn+7klT2Hv5A6wRdsReAo3xY=";
const sig2 = '12,175,100,159,238,228,149,61,135,191,144,58,193,23,108,69,224,40,223,22';
const sig1AsNumArrayString = atob(sig1).split('').map(c => c.charCodeAt(0)).toString();
console.log(sig2 === sig1AsNumArrayString)
...