programing

Node.js Crypto를 사용하여 HMAC-SHA1 해시를 생성하는 방법은 무엇입니까?

goodsources 2022. 9. 14. 22:30
반응형

Node.js Crypto를 사용하여 HMAC-SHA1 해시를 생성하는 방법은 무엇입니까?

해시를 만들고 싶다I love cupcakes(키로 서명)abcdeg)

Node.js Crypto를 사용하여 해시를 작성하려면 어떻게 해야 합니까?

암호화 매뉴얼: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')

몇 년 전 일설에 의하면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 를 참조해 주세요.스트리밍 방식을 사용하는 더 많은 예를 제시합니다.

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 문자열이기 때문에

해시 알고리즘을 서명하고 검증하기 위한 모든 샘플 코드에도 불구하고, 저는 여전히 그것을 작동시키기 위해 꽤 많은 실험과 조정이 필요했습니다.여기 모든 엣지 케이스가 포함된 작업 샘플이 있습니다.

URL은 안전하며(즉, 인코딩할 필요가 없음), 만료 시간이 걸리며 예기치 않게 예외가 발생하지 않습니다.Day.js에는 의존관계가 있지만 다른 날짜 라이브러리로 대체하거나 자체 날짜 비교를 수행할 수 있습니다.

TypeScript로 작성:

// signature.ts
import * as crypto from 'crypto';
import * as dayjs from 'dayjs';

const key = 'some-random-key-1234567890';

const replaceAll = (
  str: string,
  searchValue: string,
  replaceValue: string,
) => str.split(searchValue).join(replaceValue);

const swap = (str: string, input: string, output: string) => {
  for (let i = 0; i < input.length; i++)
    str = replaceAll(str, input[i], output[i]);

  return str;
};

const createBase64Hmac = (message: string, expiresAt: Date) =>
  swap(
    crypto
      .createHmac('sha1', key)
      .update(`${expiresAt.getTime()}${message}`)
      .digest('hex'),
    '+=/', // Used to avoid characters that aren't safe in URLs
    '-_,',
  );

export const sign = (message: string, expiresAt: Date) =>
  `${expiresAt.getTime()}-${createBase64Hmac(message, expiresAt)}`;

export const verify = (message: string, hash: string) => {
  const matches = hash.match(/(.+?)-(.+)/);
  if (!matches) return false;

  const expires = matches[1];
  const hmac = matches[2];

  if (!/^\d+$/.test(expires)) return false;

  const expiresAt = dayjs(parseInt(expires, 10));
  if (expiresAt.isBefore(dayjs())) return false;

  const expectedHmac = createBase64Hmac(message, expiresAt.toDate());
  // Byte lengths must equal, otherwise crypto.timingSafeEqual will throw an exception
  if (hmac.length !== expectedHmac.length) return false;

  return crypto.timingSafeEqual(
    Buffer.from(hmac),
    Buffer.from(expectedHmac),
  );
};

다음과 같이 사용할 수 있습니다.

import { sign, verify } from './signature';

const message = 'foo-bar';
const expiresAt = dayjs().add(1, 'day').toDate();
const hash = sign(message, expiresAt);

const result = verify(message, hash);

expect(result).toBe(true);

언급URL : https://stackoverflow.com/questions/7480158/how-do-i-use-node-js-crypto-to-create-a-hmac-sha1-hash

반응형