Node.js Crypto 모듈


사용자 비밀번호 보관 문제나 암호화된 데이터 전송 등, 웹 애플리케이션에서 암호화는 매우 중요한 숙제입니다. 노드에서는 암호화를 위해 crypto 모듈을 제공합니다.

이번 장에서는 crypto 모듈에 대한 사용법을 알아볼 예정입니다. 암호화 기법에 대한 자세한 내용은 아래의 포스팅을 참고하세요.

pbkdf2 - 단방향 암호화

단방향 암호화 알고리즘은 암호화만 할 수 있고 복호화는 할 수 없는 암호화 방식을 말합니다. 이러한 단방향 암호화 알고리즘은 각각의 암호화된 해시에 대응하는 원문에 대한 데이터를 가지고 일일히 대조해 가면서 비교해야 원문을 찾아낼 수 있습니다.

웹 애플리케이션에서 단방향 암호는 사용자 비밀번호 관리에 사용됩니다. 사용자의 비밀번호는 데이터베이스에 평문 그대로 저장하는 것이 아니라 단방향 암호화 기법을 사용해 암호화 해서 저장해 놓습니다. 그 후 사용자가 비밀번호를 입력해 로그인 할 때에는 사용자가 입력한 비밀번호를 암호화 해서 데이터베이스에 저장된 암호와 동일한 지 비교하는 방식으로 사용자 인증을 처리합니다.

이렇게 하면 데이터베이스가 해킹 당하더라도 해커는 사용자의 비밀번호를 알 수 없으므로 ‘비밀번호는 노출되지 않았다’ 라고 공지라도 띄울수 있게됩니다.

  • Hash : 아무튼 이러한 단방향 암호화 알고리즘은 해시 기법을 사용해 이루어 집니다. 해시 알고리즘은 문자열을 특정 규칙을 이용해 다른 문자열로 치환하는 방식입니다. 해시 알고리즘으로는 md5, sha1, sha256, sha512 등이 있으나 md5, sha1은 이미 깨졌으므로 비밀번호 보관 용도로 사용할 수는 없습니다. 최소한 sha256 이상을 사용해야 안전합니다.

  • Salt : 해시 알고리즘으로 암호화 하기 전에 우선 평문 암호에 salt라고 불리는 랜덤한 문자열을 붙인 후 암호화를 합니다. 이렇게 하여 원본 암호를 더 찾기 어렵게 만듭니다.

  • Key stretching : salt와 hash만으로도 부족하기에 실사용에서는 키 스트레칭이라는 기법을 함께 사용합니다. 이는 평문 암호에 salt를 치고 해시 암호화를 하는 작업을 수만~수십만번 반복해서 암호화 하는 방법입니다. 이러한 방식으로는 pbkdf2, bcrypt, scrypt 등의 알고리즘이 있습니다.

  • crypto 모듈에서는 이러한 키스트레칭 기법 중 pbkdf2 메서드를 제공합니다.

pbkdf2 메서드의 각 매개변수는 순서대로 비밀번호, 솔트, 스트레칭 반복횟수, 바이트 길이, 다이제스트 방법, 콜백으로 구성되어 있습니다.

const crypto = require('crypto');

crypto.pbkdf2('secret', 'salt', 100000, 64, 'sha512', (err, derivedKey) => {
  if (err) throw err;
  console.log(derivedKey.toString('hex'));  // '3745e48...08d59ae'
});

이 예에서는 “secret”이라는 비밀번호에 “salt” 라는 문자열을 붙힌 후 sha512 기법으로 암호화하는 작업을 십만번 반복하여 해시 암호를 생성하였습니다.

crypto 모듈에는 이외에도 양방향 암호화, 키생성 등 다양한 암호화 알고리즘을 제공합니다.