JavaScript — эквивалент Hash_hmac в Node.js

У меня есть код, который работает в моем приложении PHP. В PHP я подписываю URL следующим кодом:

private static function __getHash($string)
{
return hash_hmac('sha1', $string, self::$__secretKey, true);
}

Я пытаюсь подписать URL-адрес таким же образом в приложении Node.js. Вот что я пытаюсь:

S3.prototype.getHash = function(string){
var key = this.secret_key;
var hmac = crypto.createHash('sha1', key);
hmac.update(string);
return hmac.digest('binary');
};

Однако я получаю следующую ошибку:

Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте свой ключ и метод подписи.

Эти фрагменты кода делают то же самое? Я что-то пропустил?

6

Решение

Основная проблема здесь заключается в том, что вы используете createHash который создает хэш, а не createHmac который создает HMAC.

+ Изменить createHash в createHmac и вы должны найти, что это дает тот же результат.

Это результат, который вы должны ожидать:

chris /tmp/hmac $ cat node.js
var crypto = require('crypto');
var key = 'abcd';
var data = 'wxyz';

function getHash(string){
var hmac = crypto.createHmac('sha1', key);
hmac.update(string);
return hmac.digest('binary');
};

process.stdout.write(getHash(data));

chris /tmp/hmac $ cat php.php
<?php
$key = "abcd";
$data = "wxyz";
function __getHash($string)
{
global $key;
return hash_hmac('sha1', $string, $key, true);
}

echo utf8_encode(__getHash($data));

chris /tmp/hmac $ node node.js | base64
WsOKw4xgw4jDlFHDl3jDuEPDuCfCmsOFwoDCrsK/w6ka
chris /tmp/hmac $ php php.php | base64
WsOKw4xgw4jDlFHDl3jDuEPDuCfCmsOFwoDCrsK/w6ka
4

Другие решения

Этот ответ от Криса хорош, если вы портируете hash_hmac с последним параметром true, В этом случае создается двоичный файл, как в случае с JavaScript-скриптом Криса.

Чтобы добавить к этому, этот пример:

 $sign = hash_hmac('sha512', $post_data, $secret);

Будет перенесен с помощью функции, например, в nodejs:

const crypto = require("crypto");

function signHmacSha512(key, str) {
let hmac = crypto.createHmac("sha512", key);
let signed = hmac.update(new Buffer(str, 'utf-8')).digest("hex");
return signed
}

Разница здесь в том, что когда вы пропускаете последний аргумент hash_hmac (или устанавливаете его на что-то не true), он ведет себя так, как определено в PHP документы:

При значении TRUE выдает необработанные двоичные данные. FALSE выводит строчные буквы

Чтобы сделать это с помощью node.js, мы используем digest('hex') как вы можете видеть в фрагменте.

6

По вопросам рекламы [email protected]