2016-04-28 8 views
4

PHPアプリケーションで動作するコードがあります。私は次のコードでURLに署名PHPで:Node.jsのHash_hmac相当のファイル

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'); 
}; 

をしかし、私は次のエラーを取得しています:

The request signature we calculated does not match the signature you provided. Check your key and signing method.

は、コードのこれらの作品は、同じことを行うのですか?何か不足していますか?

+0

2つのハッシュの出力を比較して、同じことをするかどうかを確認します。 – Brody

+0

ノードの 'crypto.createHash'メソッドはHMACではなくハッシュを計算するため、キーを取得しません。 – Chris

+0

@Chris、理論的には、それを 'createHmac'に変更するとその問題は解決されますか? –

答えて

1

ここでの主な問題は、createHmacではなく、HMACを作成するcreateHashを使用してハッシュを作成することです。

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 
+0

私はまだ署名が一致しないこと。どんな考え? –

+0

よくバイナリデータをどのように比較していますか?文字列として比較する場合は、エンコードが正しいことを確認する必要があります。私は出力を添付しました。メモPHPの出力をlatin-1からUTF-8に、base64を両方の出力にエンコードして比較を容易にしました。 – Chris

+0

Sara:hash_hmacはデフォルトで16進ダイジェストを生成します – keyvan

2

あなたは最後のパラメータは、trueことでhash_hmacを移植する場合は、クリスから、この答えは良いです。この場合、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の定義に従って動作します。

When set to TRUE, outputs raw binary data. FALSE outputs lowercase hexits.

node.jsでこれを行うには、スニペットにあるようにdigest('hex')を使用します。