Node.js暗号を使用してHMAC-SHA1ハッシュを作成するにはどうすればよいですか?


回答:


366

暗号のドキュメント:http : //nodejs.org/api/crypto.html

const crypto = require('crypto')

const text = 'I love cupcakes'
const key = 'abcdeg'

crypto.createHmac('sha1', key)
  .update(text)
  .digest('hex')

'hex'は必ずしも必要ではありません。たとえば、ルビと同等のhmacダイジェストを実行する場合などです。
htafoya 2018

6
そして、ハッシュを検証するために、あなたが使用する必要がありますcrypto.timingSafeEqual(Buffer.from(a), Buffer.from(b))stackoverflow.com/questions/31095905/...
baptx

1
サークルは完成しました:nodejs.org/api/crypto.html#crypto_crypto
Ricardo Tomasi

98

数年前、レガシーメソッドであるupdate()と言われdigest()、新しいストリーミングAPIアプローチが導入されました。今、ドキュメントはどちらの方法も使用できると言います。例えば:

var crypto    = require('crypto');
var text      = 'I love cupcakes';
var secret    = 'abcdeg'; //make this your secret!!
var algorithm = 'sha1';   //consider using sha256
var hash, hmac;

// Method 1 - Writing to a stream
hmac = crypto.createHmac(algorithm, secret);    
hmac.write(text); // write in to the stream
hmac.end();       // can't read from the stream until you call end()
hash = hmac.read().toString('hex');    // read out hmac digest
console.log("Method 1: ", hash);

// Method 2 - Using update and digest:
hmac = crypto.createHmac(algorithm, secret);
hmac.update(text);
hash = hmac.digest('hex');
console.log("Method 2: ", hash);

ノードv6.2.2およびv7.7.2でテスト済み

https://nodejs.org/api/crypto.html#crypto_class_hmacを参照してください。ストリーミングアプローチの使用例をさらに示します。


ワンライナーではなく、通話をデイジーチェーン接続することはできません...しかし、このアプローチを使用します。
tfmontague 2014

2
私の人生のために、私はこの仕事をすることができません。hmac.read()は "[object SlowBuffer]"を返し、hmac.read()。toString( 'hex');を使用して内容を読み取ろうとすると、期待値がわかりません。アップデート/ダイジェストの非推奨のアプローチを使用すると、期待される文字列が返されます。これを使用して、サードパーティのPOSTからサーバーへの署名を検証します。何が起こっているのですか?
AngraX 14

おそらく、データがストリームにフラッシュされる前にhmac.readが発生していますか?多分hmac.readはストリームのfinishイベントによって駆動されるべきですか?
デイブ、

実際にあなたが投稿したリンクは明示的にの使用について言及しており、ではupdateありませんwrite。私は混乱しています、これは今のベストプラクティスですか?あなたが言うほどはっきりとそれを伝えるリソースを見つけることができません。
SCBuergel.eth 2016

5
2016年11月の時点で、digestupdateていない非推奨となっておよびドキュメントで紹介されています:nodejs.org/api/crypto.html#crypto_class_hmac。ストリームから読み取る場合にのみ、ストリームAPIを使用することをお勧めします。
Ricardo Tomasi

22

グワーダーのソリューションhash = hmac.read();は、ストリームのファイナライズが完了する前に発生するため、機能しません。したがって、AngraXの問題。また、hmac.writeこの例ではステートメントは不要です。

代わりにこれを行います:

var crypto    = require('crypto');
var hmac;
var algorithm = 'sha1';
var key       = 'abcdeg';
var text      = 'I love cupcakes';
var hash;

hmac = crypto.createHmac(algorithm, key);

// readout format:
hmac.setEncoding('hex');
//or also commonly: hmac.setEncoding('base64');

// callback is attached as listener to stream's finish event:
hmac.end(text, function () {
    hash = hmac.read();
    //...do something with the hash...
});

もっと正式に、もし望むなら、ライン

hmac.end(text, function () {

書くことができる

hmac.end(text, 'utf8', function () {

この例では、テキストはutf文字列なので


間違いです。コールバックを追加する必要はありません。このストリームは同期的で、end()が呼び出された直後に読み取ることができます。最も魅力的なことは、それが公式ドキュメントに書かれているが、誰もが自分の中で5(ベント)セントを配置する必要があります。
stroncium

あなたはトローリングしていますか?おそらく、ドキュメントを読む必要があります。終了イベントの前にストリームを読み取ろうとすると、失敗します。
Dave、

1
[からnodejs.org/api/crypto.html#crypto_class_hmac] It is a stream that is both readable and writable. The written data is used to compute the hmac. Once the writable side of the stream is ended, use the read() method to get the computed digest.ときあなたはそれを読んで書き込み可能な側面が終了し、あなたはときのためにも待つ必要はありません読める側になる読める(それは確かにありませんが)。ドキュメントを読んでください。
ストロンチウム2015年

createHmacはストリームを作成します。上記で引用したドキュメンテーション行の「終了」は、hmac.end(...)呼び出されたことを意味しません。「終了」は、ストリームが終了イベント発生させたことを意味します。これが、コマンドがコールバックを受け入れる理由です。end()メソッドが呼び出された後、ストリームは、基になるシステムにデータをフラッシュするための時間を必要とします。終了イベントが発生する前にread()を呼び出すと、失敗します。GwerderのコードをJSbinに貼り付けて、自分の目で確かめてください。Streamsのドキュメントを読んで、その仕組みを理解する必要があります。
Dave

私はしばらくの間本番コードで使用しており、地獄のように安定しています。正直なところ、JSBinが何であるかはわかりませんが、nodejsでサポートされているコードをコピーと貼り付けだけで試しましたが、これも機能します。ドキュメントに追加の意味を想像するべきではありません。「終了」は、ドキュメントのすべての場所で常に「終了」を意味します。繰り返しますが、ストリームには2つの側面があると誤解しているようです。また、ドキュメントではread()書き込み可能な側が終了したときにユーザーが使用できることが明示されており、終了イベントについては何もありません。
ストロンチウム
弊社のサイトを使用することにより、あなたは弊社のクッキーポリシーおよびプライバシーポリシーを読み、理解したものとみなされます。
Licensed under cc by-sa 3.0 with attribution required.