Node.js Crypto를 사용하여 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')

예를 들어 루비와 같은 hmac 다이제스트를 수행하기 위해 '16 진수 '가 항상 필요한 것은 아닙니다.
htafoya

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 ()는 "[object SlowBuffer]"를 반환하고 hmac.read (). toString ( 'hex');를 사용하여 내용을 읽으려고하면 예상 값을 얻지 못했습니다. 사용되지 않는 업데이트 / 다이제스트 접근 방식을 사용하면 예상되는 문자열이 반환됩니다. 이것을 사용하여 타사 POST에서 내 서버로의 서명을 확인합니다. 어떤 아이디어가 일어나고 있습니까?
AngraX

아마도 데이터가 스트림으로 플러시되기 전에 hmac.read가 발생하고 있습니까? 아마도 스트림의 종료 이벤트로 hmac.read를 구동해야합니까?
Dave

실제로 귀하가 게시 한 링크는의 사용 update과 그렇지 않은 것을 명시 적으로 언급합니다 write. 혼란스러워, 지금 가장 좋은 방법은 무엇입니까? 언급 한대로 명확하게 알려주는 자료를 찾을 수 없습니다.
SCBuergel.eth

5
11 월 2016로서, digest그리고 update하지 사용되지 않습니다 및 문서에 등장 : nodejs.org/api/crypto.html#crypto_class_hmac를 . 스트림에서 읽는 경우에만 스트림 API를 사용하는 것이 좋습니다.
Ricardo Tomasi

22

hash = hmac.read();스트림이 완료되기 전에 Gwerder의 솔루션이 작동하지 않습니다 . 따라서 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 센트를 구부려
야한다는 것

당신은 트롤하고 있습니까? 아마도 문서를 읽어야 할 것입니다. finish 이벤트 전에 스트림을 읽으려고하면 실패합니다.
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. 때 당신은 그것을 읽고 쓰기 측이 종료 , 당신은 경우에 대해서도 기다릴 필요가 없습니다 읽을 수있는 면이된다 읽을 수 (가 확실하지하지만). 설명서를 읽으십시오.
스트론튬

createHmac는 스트림을 만듭니다 . 위에서 인용 한 문서 라인에서 " ended "는 hmac.end(...)호출 되지 않았다는 것을 의미하지 않습니다 . " ended "는 스트림이 finish 이벤트를 발생 시켰기 때문에 명령이 콜백을 수락하는 이유입니다. end () 메소드가 호출 된 후, 스트림은 기본 시스템으로 데이터를 플러시하는 시간이 필요합니다. finish 이벤트가 발생하기 전에 read ()를 호출하면 실패합니다. 계속해서 Gwerder의 코드를 JSbin에 붙여 넣고 직접 확인하십시오. 작동 방식을 이해 하려면 Streams 설명서를 읽어야 합니다.
Dave

나는 그것을 한동안 생산 코드에서 사용했으며 지옥처럼 안정적입니다. 솔직히 JSBin이 무엇인지 모르지만 복사 붙여 넣기만으로 nodejs에서 지원되는 코드를 시도했지만 작동합니다. 문서화에 대한 추가 의미를 상상해서는 안됩니다. "종료"는 항상 문서의 모든 곳에서 "종료"를 의미합니다. 다시 말하지만, 스트림에는 양면이 있다는 것을 오해하는 것 같습니다. 그리고 문서에 명시 적으로 사람이 사용할 수있는 언급되는 read()쓰기 끝났다면, 마무리 이벤트에 대한 아무것도 없다.
스트론튬
당사 사이트를 사용함과 동시에 당사의 쿠키 정책개인정보 보호정책을 읽고 이해하였음을 인정하는 것으로 간주합니다.
Licensed under cc by-sa 3.0 with attribution required.