У меня есть код, который работает в моем приложении 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');
};
Однако я получаю следующую ошибку:
Рассчитанная нами подпись запроса не соответствует предоставленной вами подписи. Проверьте свой ключ и метод подписи.
Эти фрагменты кода делают то же самое? Я что-то пропустил?
Основная проблема здесь заключается в том, что вы используете 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
Этот ответ от Криса хорош, если вы портируете 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')
как вы можете видеть в фрагменте.