Як використовувати криптовалюту Node.js для створення хеша HMAC-SHA1?


Відповіді:


369

Документація на крипто: 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')

"Шістнадцятковий" не завжди потрібен, наприклад, для того, щоб робити дайджест hmac-еквівалента рубіну.
хтафоя

6
І перевірити хеш, ви повинні використовувати crypto.timingSafeEqual(Buffer.from(a), Buffer.from(b)): stackoverflow.com/questions/31095905 / ...
baptx


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

2
Я не можу за все життя змусити цю роботу. hmac.read () повертає "[об'єкт SlowBuffer]", і якщо я спробую прочитати вміст, використовуючи hmac.read (). toString ('hex'); Я не отримую очікуваного значення. Якщо я використовую застарілий підхід оновлення / дайджесту, він повертає очікуваний рядок. Я використовую це для перевірки підпису третьої сторони POST на своїх серверах. Якісь ідеї, що відбувається?
AngraX

Можливо, hmac.read відбувається до того, як дані будуть передані в потік? Можливо, hmac.read повинен бути керований подією фінішу потоку?
Дейв

Насправді посилання, яке ви розмістили, прямо вказує на використання, updateа не write. Я розгублений, яка найкраща практика зараз? Я не можу знайти ресурси, які говорять про це так само чітко, як ви це згадуєте.
SCBuergel.eth

5
Станом на 2016 листопада, digestі updateще НЕ були застарілими і описані в документації: nodejs.org/api/crypto.html#crypto_class_hmac . Я рекомендую використовувати API потоку, лише якщо ви читаєте з потоку.
Рікардо Томасі

22

Рішення Gwerder не працює, тому що 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-рядок


Ви помиляєтеся, не потрібно додавати зворотний дзвінок. Цей потік синхронний і читабельний відразу після виклику кінця (). Найцікавіше, що це написано в офіційній документації, але кожен повинен покласти свої 5 (зігнуті) копійки.
stroncium

Ви тролінг? Можливо, вам варто прочитати документацію. Якщо ви спробуєте прочитати потік перед фінішною подією, він не вийде.
Дейв

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. Ви читали, коли записується сторона закінчилася , вам не потрібно навіть чекати, коли прочитується сторона стає читається (хоча це , звичайно , робить). Прочитайте, будь ласка, свою документацію.
стронцій

createHmac створює потік . " закінчено " в документаційному рядку, який ви цитуєте вище, не означає, hmac.end(...)що його викликали, " закінчено " означає, що потік підняв подію фінішу , тому команда приймає зворотний виклик. Після виклику методу end () потоку потрібен час для передачі даних до базової системи. Якщо ви зателефонуєте прочитати () перед тим, як подія фінішу буде піднята, вона вийде з ладу. Далі вставте код Gwerder у JSbin і переконайтеся самі. Вам слід прочитати документацію Streams, щоб зрозуміти, як вона працює.
Дейв

Я використовував його у виробничому коді деякий час, і він стабільний як пекло. Я, чесно кажучи, не знаю, що таке JSBin, але я також спробував підтримуваний код у nodejs із просто копіювати-вставити, і він також працює. Не варто уявляти додаткові значення документації. "закінчився" завжди означає "закінчився" скрізь у документації. Знову ж таки, ти, здається, неправильно розумієш, що потік має дві сторони. А в документації чітко зазначено, що людина може використовувати, read()коли закінчилася записувана сторона, і немає нічого про закінчення події.
стронцій
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.