2016-09-16 12 views
0

Nodejsを使用して、XMLメッセージのbase64でエンコードされた署名であるHMAC SHA256を生成しようとしています。私は現在、PHPを使って署名生成を行っています。HMACを使用したデータのbase64エンコーディングに関する問題

このプロセスはかなり単純なようです。Node64でbase64でエンコードされた値を生成することはできますが、何らかの理由で値が一致せず、PHPを使用するよりもはるかに短くなります。

以下、サンプルのPHPスクリプトと結果、Nodejの実装と結果を示しました。 Nodejsでは、私はネイティブの暗号モジュールを使用しています。

は結果
// PHP implementation 

$xml = <<<EOD 
<?xml version='1.0' encoding='UTF-8'?> 
<dataset> 
    <record> 
    <id>1</id> 
    <first_name>Carlos</first_name> 
    <last_name>Ruiz</last_name> 
    <email>[email protected]</email> 
    <gender>Male</gender> 
    <ip_address>156.225.191.154</ip_address> 
    </record> 
</dataset> 
EOD; 

$secret = 'secret'; 
$sig = base64_encode(hash_hmac('sha256', $xml, $secret)); 

echo $sig; 

: は結果ODhkYTc1YmQzNzc0NWUyNDJlNjY3YTY1NzZhYzFhZGYwOTJlMTIxODdjNzYxOWYyNGQxNGExOGVkYTIyZDQ0ZQ==

// Nodejs implementation 

var crypto = require('crypto'); 

fs.readFile('example.xml', 'utf-8', function(err, data) { 
    function sig(str, key) { 
    return crypto.createHmac('sha256', key) 
     .update(str) 
     .digest('base64'); 
    } 
    console.log(sig(data, 'secret')); 
}); 

: 私はこれを理解し、スタックオーバーフローを使用しての年の+の後にしようとして一日を過ごしてきたiNp1vTd0XiQuZnpldqwa3wkuEhh8dhnyTRShjtoi1E4=

、これが私の最初のものです質問。

ご協力いただければ幸いです!

+0

私はあなたの最初の例では、あなたのxmlファイルは、ファイルが、文字列ではありません注意してください。ですから、 'example.xml'の中の実際のXMLは何ですか?つまり、sha256のプリントは256ビット、つまり32バイトで、base64変換では約4/3が大きくなるため、base64のHMACプリントの長さは約42文字です。したがって、Node.jsの結果は確かに正しい長さになります(4バイトに合わせるためにパディング '= 'を持つ43文字)が正しい長さに見えますが、PHP文字列は絶対にそうではありません。 * waaaaay *が長すぎます。 –

+0

返事をありがとう、mscdexの答えから、私は何をする必要があるかを理解することができました。彼が説明したように、私の例では、hash_hmacは16進数でエンコードされた文字列を返していました。その情報を使って、ダイジェストとして 'hex'を使い、文字列に変換し、その文字列をbase64としてエンコードすることでnodejsコードを動作させることができました。 – oudelitonalituridalp

+0

**あなたがbase64でエンコードされたHMAC値を生成していないことを認識していれば**、あなたのソフトウェアの優れたスリーパーバグです。消費コードでbase64でエンコードされた真のSHA-256 HMAC値を期待することは、ここで無限に良い解決策です。 –

答えて

0

ここでの問題は、($raw_outputパラメータhereを参照)PHPのhash_hmac()は、デフォルトでは16進数でエンコードされた文字列を返すということですので、あなたの代わりに、生の、バイナリ結果の実際の16進文字列を、base64でエンコードされています。

$sig = base64_encode(hash_hmac('sha256', $xml, $secret)); 

だから、これを変更

$sig = base64_encode(hash_hmac('sha256', $xml, $secret, true)); 
+0

返信いただきありがとうございます!私はPHPが特定の/期待された方法で機能していると思っていたので、私は思うように思っていました。 あなたの答えから、ダイジェストとして 'hex'を使用して文字列に変換し、base64エンコーディングして必要な結果を得ることができました。 – oudelitonalituridalp

関連する問題