PHPアプリで動作しているコードがあります。PHPでは、次のコードでURLに署名します。
private static function __getHash($string)
{
return hash_hmac('sha1', $string, self::$__secretKey, true);
}
Node.jsアプリケーションで同じ方法でURLに署名しようとしています。これは私が試していることです:
S3.prototype.getHash = function(string){
var key = this.secret_key;
var hmac = crypto.createHash('sha1', key);
hmac.update(string);
return hmac.digest('binary');
};
ただし、次のエラーが発生します。
計算したリクエストの署名が、指定した署名と一致しません。キーと署名方法を確認してください。
これらのコードは同じことをしますか?私は何かが足りないのですか?
ここでの主な問題は、HMACを作成するcreateHash
ではなく、ハッシュを作成するcreateHmac
を使用していることです。
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
である場合、Chrisからのこの回答は適切です。この場合、Chrisの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 docs)で定義されているように動作することです。 :
TRUEに設定すると、生のバイナリデータが出力されます。 FALSEは小文字のヘキシットを出力します。
Node.jsでこれを行うには、スニペットに示されているようにdigest('hex')
を使用します。