비밀번호 암호화 어떻게 해야 할까? Node.js에서 안전하게 처리하는 법
2023. 4. 20. 20:00
728x90

[Node.js] 비밀번호 암호화 구조 정리 – Salt와 Key Stretching은 왜 필요할까?

실무에서 사용자 비밀번호를 안전하게 저장하기 위해선 단순한 해시 처리만으로는 부족합니다.
이 포스트에서는 Salt, Key Stretching을 이용한 안전한 비밀번호 암호화 방식에 대해 정리합니다.


솔트(Salt)란?

해시 함수에 추가적으로 더해지는 무작위 데이터입니다.
같은 문자열이라도 항상 다른 해시 결과를 얻기 위해 사용됩니다.

왜 필요한가요?

예를 들어, 아래 문자열을 SHA512로 해시해봅니다:

'jeong-park' → 2C1E444B...D5935AA

누가 해도 같은 결과가 나옵니다.
⇒ 이를 통해 레인보우 테이블 공격 등으로 역추적이 가능해집니다.


Key Stretching이란?

해시 함수를 여러 번 반복하여 처리 속도를 늦추고 보안을 높이는 방법

효과

  • 무차별 대입 공격(Brute-force) 방지
  • 레인보우 테이블 무력화

코드 예시 – PBKDF2 기반 비밀번호 암호화

const crypto = require('crypto');
const util = require('util');

const pbkdf2Promise = util.promisify(crypto.pbkdf2);
const randomBytesPromise = util.promisify(crypto.randomBytes);

// 1. Salt 생성
const createSalt = async () => {
  const new_salt = await randomBytesPromise(64);
  return new_salt.toString("base64");
};

// 2. 비밀번호 + Salt => 반복 해싱
const createHashedPassword = async (password, salt) => {
  const key = await pbkdf2Promise(password, salt, 100000, 64, "sha512");
  return { hashedPassword: key.toString("base64"), salt };
};

// 3. 입력값 검증
const verifyPassword = async (password, userSalt, userPassword) => {
  const key = await pbkdf2Promise(password, userSalt, 100000, 64, 'sha512');
  return key.toString('base64') === userPassword;
};

구조 요약

  1. 사용자 비밀번호 입력
  2. 랜덤한 솔트 생성
  3. password + saltPBKDF2N번 해싱
  4. 해시된 비밀번호 저장
  5. 로그인 시 동일 방식으로 비교

정리 포인트

요소 설명
Salt 동일한 입력 → 다른 해시 결과
Key Stretching 계산 시간 증가 → 보안 강화
PBKDF2 Node.js 내장 해시 알고리즘 (HMAC + 반복)

참고

반응형