본문 바로가기
카테고리 없음

[암호화] Node.js의 암호화 모듈

by hbIncoding 2024. 10. 2.

1. bcrypt

  • Blowfish 암호를 기반으로 둔 암호화 해시 함수
  • 입력값을 고정된 길이의 출력값으로 변환
  • 입력값을 여러 번 반복해서 암호화하기 때문에 보안성이 매우 높다는 장접이 있지만, 안전한 암호화를 위해 암호화 속도가 느리다는 단점이 있다.
  • 특징
    • 고유 소금 사용 : 각 비밀번호에 고유한 소금을 추가하여 동일한 비밀번호라도 매번 다른 해시 값을 생성
    • 비용 인자(cost factor) : 비용 인자는 해시 연산의 복잡도를 설정하는 값으로, 해시 연산을 여러 번 반복하여 공격에 대한 저항력을 강화.
    • 보편적인 사용 : bcrypt는 광범위 하게 사용되며, 많은 시스템에서 지원
  • 장점
    • 보안성 : 해시 연산에 반복을 적용해 공격자의 비밀번호 추측을 어렵게 만듦.
    • 소금 적용: 소금을 적용해 동일한 비밀번호라도 해시 값이 다르게 나와, 사전 공격을 방지.
    • 성숙한 라이브러리: 여러 해 동안 검증된 라이브러리로, 신뢰성이 높음.
  • 단점
    • 성능: 비용 인자를 높게 설정하면 해시 연산이 느려짐. 따라서 너무 높은 값을 설정하면 성능에 영향을 줄 수 있음.
    • 더 강력한 알고리즘 등장: argon2 같은 더 안전한 방법이 등장하면서 상대적으로 덜 최신 기술로 분류될 수 있음.
// 설치
npm install bcrypt

// 사용 예시
const bcrypt = require('bcrypt');

// 비밀번호 해시 생성
const password = 'user_password';
const saltRounds = 10;

bcrypt.hash(password, saltRounds, (err, hash) => {
  if (err) throw err;
  // 해시된 비밀번호를 DB에 저장
  console.log('Hashed password:', hash);
});

// 비밀번호 검증
bcrypt.compare('user_password', hash, (err, result) => {
  if (result) {
    console.log('Password is correct');
  } else {
    console.log('Password is incorrect');
  }
});
  • saltRounds : 해시 작업을 몇 번 반복할지 결정하는 인자, 값이 클수록 안전하지만 속도가 느려진다.

2. argon2

  • 2015년 비밀번호 해시 함수 대회에서 우승한 알고리즘
  • bcrypt 보다 더 강력한 보안을 제공
  • 메모리 사용량을 조정하여 해시 연산의 복잡도를 조정 할 수 있다.
  • 특징
    • 메모리 사용량 조정: CPU뿐만 아니라 메모리 사용량도 설정할 수 있어, 해시 계산이 메모리 소모가 많은 작업이 되어 공격을 더욱 어렵게 만듦.
    • **비용 인자(cost factor)**와 병렬화 인자(parallelism factor): 연산의 복잡도뿐만 아니라, 메모리 소비량과 병렬 처리를 설정하여 보다 강력한 보안을 제공.
    • 3가지 버전 지원: argon2i, argon2d, argon2id로 구분되며, 각각 메모리 하드닝과 관련된 보안 수준을 다르게 적용할 수 있음.
  • 장점
    • 최신 보안 표준: 가장 최근의 비밀번호 해시 함수 대회에서 우승한 알고리즘으로, 높은 보안성을 제공.
    • 메모리 기반 공격 저항: 메모리와 CPU 사용량을 조절할 수 있어 특정 공격에 대한 저항력이 강화됨.
    • 유연한 설정: 연산량과 메모리 사용량을 상황에 맞게 조절할 수 있어 유연성이 뛰어남.
  • 단점
    • 성능: 높은 보안을 제공하기 위해 메모리와 CPU를 많이 사용할 수 있으며, 이에 따른 성능 저하 가능성.
    • 복잡한 설정: 다양한 인자를 조정할 수 있지만, 그만큼 설정이 복잡할 수 있음.
// 설치
npm install argon2

// 사용 예시
const argon2 = require('argon2');

// 비밀번호 해시 생성
async function hashPassword(password) {
  try {
    const hash = await argon2.hash(password);
    console.log('Hashed password:', hash);
  } catch (err) {
    throw err;
  }
}

// 비밀번호 검증
async function verifyPassword(password, hash) {
  try {
    if (await argon2.verify(hash, password)) {
      console.log('Password is correct');
    } else {
      console.log('Password is incorrect');
    }
  } catch (err) {
    throw err;
  }
}

hashPassword('user_password');

 

3. crypto

  • 다양한 암호화 알고리즘을 제공하는 라이브러리
  • bcrypt와 달리, 암호화 범위가 넓어서 인증서나 키 관리 등에서 사용된다. 
    • 대칭키 암호화, 비대칭키 암호화, 해시 함수 등
  • bcrypt와 달리 암호화 속도가 빠르다는 장점이 있다.

1)PBKDF2( Password-Based Key Derivation Function 2)

  • 암호화된 키를 생성하는 함수
  • 오래된 해시 함수로, 반복 연산을 통해 비밀번호를 해시합니다. 
  • 다양한 해시 알고리즘(SHA-256, SHA-512 등)을 기반으로 동작하며, 소금을 추가해 암호화된 키를 생성합니다.
  • 특징
    • 반복 연산: 설정된 반복 횟수만큼 해시 연산을 수행해 보안을 강화.
    • 다양한 해시 알고리즘 지원: 기본적으로 SHA-256이나 SHA-512 등의 알고리즘과 함께 사용됨.
    • FIPS 표준: 미 연방 정보 처리 표준(FIPS)에 따라 정의된 알고리즘으로 신뢰성이 높음.
  • 장점
    • 폭넓은 호환성: 오래된 방식이지만 여전히 많은 시스템에서 사용되며, 다양한 해시 알고리즘을 지원해 유연성도 높음.
    • 검증된 보안성: 많은 시스템에서 오랫동안 사용되어온 알고리즘으로 신뢰성 보장.
    • 적당한 성능: 비교적 빠르게 해시 연산을 수행할 수 있음.
  • 단점
    • 메모리 기반 공격에 취약: 메모리 하드닝 기능이 없어 고성능 하드웨어를 사용한 공격에 상대적으로 취약.
    • bcrypt와 argon2보다 덜 안전: 최신 보안 알고리즘에 비해 복잡한 공격에 대한 저항력이 상대적으로 떨어짐.
// 기본 사용법
const crypto = require('crypto');

// 비밀번호 해시 생성
function hashPassword(password) {
  const salt = crypto.randomBytes(16).toString('hex'); // 소금 생성
  const hash = crypto.pbkdf2Sync(password, salt, 1000, 64, `sha512`).toString(`hex`);
  return { salt, hash };
}

// 비밀번호 검증
function verifyPassword(password, salt, hash) {
  const hashVerify = crypto.pbkdf2Sync(password, salt, 1000, 64, `sha512`).toString(`hex`);
  return hash === hashVerify;
}

const { salt, hash } = hashPassword('user_password');
console.log('Salt:', salt);
console.log('Hashed password:', hash);

 

2)scrypt

  • 주로 메모리 기반 공격을 방어하기 위해 개발된 알고리즘으로, 많은 메모리를 소모하는 해시 함수를 사용합니다.
  • 특징
    • 메모리 소모: 메모리 소모량을 설정할 수 있으며, 많은 메모리를 필요로 하는 해시 연산을 통해 공격을 어렵게 만듦.
    • 메모리 하드닝: CPU뿐만 아니라 메모리 자원을 많이 사용하도록 설계되어, 대규모 병렬 처리를 통한 공격에 저항.
    • 높은 복잡성: 연산량과 메모리 사용량을 높여 공격자에게 큰 부담을 줄 수 있음.
  • 장점
    • 메모리 기반 공격 저항: 공격자가 비밀번호를 추측하려면 많은 메모리와 CPU 자원이 필요해 공격 난이도가 높아짐.
    • 강력한 보안성: 메모리 하드닝을 제공해 비밀번호 해시 연산이 매우 안전함.
    • 적용 유연성: 메모리와 CPU 사용량을 상황에 맞게 조절 가능.
  • 단점
    • 복잡한 설정: 메모리 사용량, 병렬 처리 등을 설정해야 하므로 복잡도가 높음.
    • 성능 문제: 메모리와 CPU를 많이 사용하므로 해시 연산이 느려질 수 있음.
    • 호환성 문제: 일부 시스템에서는 기본적으로 지원하지 않기 때문에, 다른 방법에 비해 적용이 어려울 수 있음.
// 사용 예시
const crypto = require('crypto');

// 비밀번호 해시 생성
crypto.scrypt('user_password', 'salt', 64, (err, derivedKey) => {
  if (err) throw err;
  console.log('Hashed password:', derivedKey.toString('hex'));
});

 

4. 결론

  • bcrypt: 신뢰성이 높고 검증된 보안성을 제공하지만, 최신 알고리즘보다 성능이 떨어질 수 있음.
  • argon2: 최신의 안전한 알고리즘으로, 유연한 설정과 강력한 보안을 제공함. 메모리 하드닝을 지원하여 높은 보안 수준을 유지.
  • PBKDF2: 오래된 방식이지만 여전히 많이 사용되며, 다양한 해시 알고리즘과 호환됨. 다만 최신 알고리즘에 비해 보안성이 다소 떨어짐.
  • scrypt: 메모리 사용량을 조절해 매우 강력한 보안을 제공하지만, 설정이 복잡하고 성능 저하 우려가 있음.