본문 바로가기
Research/Node.js

node.js 암호화 모듈 원리 및 사용법

by RIEM 2023. 12. 9.

암호화 모듈 종류

암호화 모듈 종류는 이렇게 있다.

  • SHA-2(Secure Hash Algorithm 2)
  • PBKDF2
  • Bcrypt
  • Scrypt

SHA-2

  • SHA-2은 Secure Hash Algorithm2의 약자
  • 미국 NSA에서 설계한 암호화 해시 함수
  • digest size는 224, 256, 512 bit로 해시함수로 구성된다
  • 연산속도가 빠른 GPU로 인해 password 암호화에는 부적절

PBKDF2

pbkdf2_hmac(해시함수(sha256..), password, salt, iteration, DLen)
  • ISO 표준에 적합, NIST에서 승인한 알고리즘
  • 해시함수의 컨테이너 역할
  • 검증된 해시 함수만 사용
  • 해시함수 유형, salt, 반복 회수를 지정할 수 있다

Bcrypt

bcrypt.hashpw(password, bcrypt.gensalt())
  • 현재 기준 가장 강력한 해시 메커니즘 중 하나
  • 1999년에 발표한 password-hashing function
  • Blowfish 암호 기반으로 설계한 암호화 함수
  • 다양한 플랫폼, 언어에서 사용
  • 반복횟수 늘려 연산속도를 늦출 수 있어, brute-force 공격 대비 가능

Scrypt

hashlib.scrypt(password, *, salt, n, r, p, maxmem=0, dklen=64)
  • 2009년에 공개한 key derivation function
  • brute force 공격에 대응력이 더 좋지만, 메모리, CPU 사용이 더 많다
  • OpenSSL 1.1 이상 제공하는 시스템에서만 작동

Bcrypt 사용하는 이유

SHA는 보안성은 좋다. 하지만 GPU 연산에 유리한 32비트 논리 및 산술 연산만 사용하기 때문에 GPU 이용한 공격에 취약하다.

이러한 문제를 해결하기 위해 Bcrypt 개발진은 SHA가 아닌 Blowfish로 구현했다.

공격자는 컴퓨터 자원이 한정적이기 때문에 공격자의 속도를 늦추면 암호화 해독을 방해할 수 있다.

언제 뭘 사용하나?

  • ISO-27001 보안 규정을 준수해야 하나? -> PBKDF2
  • 규정 준수할 필요가 없고 구현을 빠르게 하고싶다면? -> Bcrypt
  • 보안 시스템 고도화에 투자할 여력이 된다면? -> Scrypt

Bcrypt 모듈 사용법

소요시간 계산

const bcrypt = require('bcrypt');
const plainText = 'We love you';
for (let rounds = 9; rounds <= 15; rounds++) {
  console.time(rounds);
  bcrypt.hashSync(plainText, rounds);
  console.timeEnd(rounds);
}
9: 29.095ms
10: 57.953ms
11: 115.546ms
12: 230.657ms
13: 460.583ms
14: 923.327ms
15: 1.828s

구현

const bcrypt = require('bcrypt');
const saltRounds = 10; // 해시 사이클 횟수. 높을 수록 보안이 높지만, 시간이 더 소요된다.
const plainText = 'We love you';

bcrypt
  .genSalt(saltRounds)
  .then((salt) => {
    console.log(`salt = ${salt}`);
    return bcrypt.hash(plainText, salt);
  })
  .then((hash) => {
    console.log(`hash = ${hash}`);
  })
  .catch((err) => console.error(err.message));
salt = $2b$10$43P4D/Unkkwh11ULYdx5Ce
hash = $2b$10$43P4D/Unkkwh11ULYdx5Cez6/hHPgS2l.pTw0w9pQTWKdnvDMRCcO

검증

const bcrypt = require('bcrypt');
const hash = '$2b$10$43P4D/Unkkwh11ULYdx5Cez6/hHPgS2l.pTw0w9pQTWKdnvDMRCcO';
const plainText = 'We love you';

bcrypt
  .compare(plainText, hash)
  .then((result) => {
    console.log(`result = ${result}`); // result = true
  })
  .catch((err) => console.error(`error = ${error}`));

Reference

'Research > Node.js' 카테고리의 다른 글

node.js_fs로 csv 파일 생성하는 방법  (0) 2023.09.22
35.node.js Buffer?  (0) 2023.09.20
node.js_zip and unzip  (0) 2023.09.20
Express.js_싱글톤 패턴, 비즈니스 로직 분리  (0) 2023.03.24
Express.js_router 분리하는 방법  (0) 2023.03.24

댓글