[ Node.js ] crypto를 사용하여 비밀번호 암호화 하기

Shin·2022년 2월 24일
0

JS

목록 보기
7/8

🤷‍♂️ crypto란?

Node.js 에 내장되어 있는 내장 모듈 중 하나로 문자열을 암호화, 복호화, 해싱할 수 있도록 도와주는 모듈입니다.
Crypto에는 여러가지 암호화 방식이 있지만, 아래에선 Hash를 통해 암호화를 해보겠습니다.

❔ 암호화 방식

암호화 방식은 크게 두가지로 나뉩니다.

  • 단방향 암호화 : 복호화를 할 수 없는 암호화 방식.
  • 양방향 암호화 : 복호화가 가능한 암호화 방식.

🍀 복호화란?
-> 복호화는 암호화 된 것을 암호화 되기 전의 상태로 되돌리는 것을 말합니다.
실제 웹 서비스에서 비밀번호를 찾기를 할 때, 원래 쓰던 비밀번호를 알려주는 것이 아닌 새로운 비밀번호를 생성하는 창으로 넘어가게 되는데요.
이때 사용하는 암호화 방식이 단방향 암호화 방식 이기 때문에 그렇습니다.

🚔 Crypto 사용하기!

const crypto = require('crypto');

module.exports = (password) => {
  const hash = crypto.createHash('sha1');
  hash.update(password);
  return hash.digest("hex");
}

위 코드는 crypto를 사용하여 sh1 알고리즘을 사용하여 hex 형식으로 반환해준다.

하지만 실제 서비스를 할 때 위처럼 암호화를 진행하게 된다면 문제가 생긴다.
위처럼 코드를 작성하게 될 경우 비밀번호가 같은 유저는 암호화 된 비밀번호도 같게 된다.
그럼 공격자는 이를 통해 비밀번호를 유추해낼 수 있기 때문에 [레인보우 테이블 ]아주 위험한 방식의 암호화 방법이다.

🍀 레인보우 테이블 이란?

-> 레인보우 테이블은 해시 함수(MD5, SHA-1, SHA-2 등)을 사용하여 만들어낼 수 있는 값들을 대량으로 저장한 표이다.
이를 이용하여 Brute Force attack[무차별 공격] 등에 사용하여 암호를 찾아낸다.


🤷‍♂️ Salt를 통해 암호화 하기

Salt는 위 이미지 처럼 해시함수를 돌리기 전에 원문에 임의의 문자열을 덧붙이는 것을 말한다. 단어 뜻 그대로 원문에 임의의 문자열을 붙인다는 의미의 소금친다(salting) 는 것이다.

위 그림처럼 진행하게 될 경우 사용자마다 다른 Salt 값을 가지고 암호화 하기 때문에 안전하다.

const crypto = require('crypto')


function hashTest(password) {
  const salt = crypto.randomBytes(32).toString('hex')
  return  crypto.pbkdf2Sync(password, salt, 1, 32, 'sha512').toString('hex')
}

// 암호화
console.log(hashTest('test1234'))
console.log(hashTest('test1234'))

/*
출력
28d736a2fd011804e46355b3bbb0c14cda6ff931446649a60bd9d31611e96b4a
305bd011bd54c60617148cb71a27db2ba0212be463bcc5917ef72261ec62845d
*/

위 코드의 출력 결과를 보면 같은 비밀번호인 test1234 값을 넣어줬지만 출력 결과는 다르다는 것을 알 수 있습니다!

위 코드를 하나 하나 설명해보자면, 내장 모듈인 crypto를 사용하기 위해 불러와준 후,

randomBytes를 통해 salt를 생성해 줍니다. randomBytes의 인자로 문자열의 size를 넣어주고, toString 메소드에 인코딩 방식을 인자로 넣어주면 됩니다.

const salt = crypto.randomBytes(32).toString('hex') 는 32의 문자열 길이를 가진 랜덤 문자열을 hex 형식으로 인코딩 한다는 뜻 입니다.

그리고 pbkdf2Sync 를 통해 암호화를 진행해줍니다.
pbkdf2Sync 의 인자로는 ( 암호화 할 비밀번호, Salt, 반복 횟수, 문자열 길이, 암호화 알고리즘) 순서대로 들어가게 됩니다.
그리고 아까 randomBytes와 같이 마지막에 toString을 통해 인코딩 방식을 정해줍니다.

pbkdf2Sync 를 사용하게 된다면 아까 처럼 레인보우 테이블이 생성 될 수 없고, 각 유저마다 다른 salt와 암호화 된 비밀번호를 지니기 때문에 한 사람의 비밀번호가 누출 되었다고 해서 다른 유저들이 피해받는 상황을 방지 할 수 있습니다.

profile
누군가의 선택지가 될 수 있는 사람이 되자

0개의 댓글