coding/Node.js

비밀번호 암호화 - bcrypt

JIN_Coder 2022. 8. 17. 22:50

백앤드 서버 개발자라면 중요한 정보(비밀번호 등)를 DB에 저장할 때 입력받은 값 그대로 저장해서는 안된다.

만약 db서버가 탈취당하게 된다면, 사용자들의 정보나 중요한 내용들이 해커 손에 들어가기 때문이다.

서버의 보안이 뚫리지 않는 것이 가장 이상적인 상황이지만, 보안은 언제든 뚫릴 수 있고, 항상 강화를 해야 한다.

이때 비밀번호를 암호화하여 저장을 했다면, 탈취당하더라도, 사용자들의 정보를 조금이라도 지킬 수 있기 때문에 보험처럼 항상 암호화를 실시하여 저장을 해주어야 한다.

또한, 관리자가 사용자의 개인정보를 저장을 하지만, 비밀번호 같은 더 중요한 내용을 그대로 보거나, 저장하면 안 되기 때문에, 암화화를 하는 이유도 있다.

 

 

단방향 / 양방향 암호화

- 단방향 암호화

암호화는 할 수 있어도, 복호화하여 원래의 비밀번호를 알 수없다.

hash 알고리즘 사용 : 임의의 문자열을 고정된 길이의 다른 문자열로 변환

 

- 양방향 암호화

암호화하고, 복호화하여 원래의 비밀번호를 알 수 있다.

대칭키(비공개 키), 비대칭키(공개키)

 

대부분의 암호화는 단방향을 많이 사용한다.

비밀번호를 찾을 때 사용자 인증을 하고 나면 비밀번호를 알려주는 것이 아닌 재설정을 하는 것은 복호화를 통해 원래 비밀번호를 알지 못하기 때문에 재설정한다.

 

 

단방향 암호화

단방향 암호화는 hash 알고리즘을 사용하는데

해쉬 함수는 같은 입력값은 같은 출력 값이 나오고, 출력 값으로 입력값을 유추할 수는 없다.

 

// ex) 입력 값 / 출력값
a  => 35cbefc0691a5ebd7337dec23414baeb75ab6ecc33e78354d3adaf1e4923f8aa
b => c47340d0011ba756c6264b2be5071fea99dc8f1213163ae7383b902811a60163
c => 446474b819d6debddd55d0944e3912f33fe97bbcf6d1e5005130bb428dd1d36c
a  => 35cbefc0691a5ebd7337dec23414baeb75ab6ecc33e78354d3adaf1e4923f8aa

이렇게 암호화를 하면 보안이 뚫리더라도 해커가 입력값을 알 수 없기 때문에 조금 더 안전하다

 

하지만 이러한 방식은 값을 일일이 비교하는 작업을 통해 입력값을 유추당할 수 있다.

같은 입력값은 같은 출력 값을 나타내기 때문에 한번 뚫리면 이와 같은 입력값을 입력한 값은 전부 알아낼 수 있기 때문이다.

 

이렇게 입력값 - 출력 값을 저장해 놓는 것을 레인보우 테이블이라고 한다.

 

 

단방향 암호화 보안 강화하기

Salting과 Key Stretching을 이용하여 강력한 암호화를 할 수 있다.

 

- Salting

기존의 문자열에 추가 문자열(salt)을 붙여 새로운 문자열을 반환한다.

ex)

A유저와 B유저의 비밀번호가 같더라도 salt를 통해 다른 출력 값이 생성된다.(해쉬 알고리즘 단점 극복)

하지만, 모든 비밀번호에 같은 salt값을 사용하면 해커가 salt 값을 알아낸다면, 이 또한 보안이 취약해진다.

 

- Key Stretching

salt와 입력값을 해쉬 함수에 넣는 과정을 반복하여 여러 번의 암호화를 시도하는 것

즉, 출력 값을 느리게 산출되도록 하는 방법(빠르면 해커가 금방 산출해버리기 때문)

기존 문자열의 다이제스트를 생성하고, 생성된 다이제스트로 다시 다이제스트를 생성한다.

키 스트레칭을 99번 한 것과 100번 한 것의 생김새는 완전히 다르다.

키 스트레칭

 

 

node.js에는 기본적으로 crypto 모듈을 제공하여 crypto를 사용하여 암호화를 할 수 있다.

하지만, 여기서는 bcrypt라는 모듈을 설치하여 사용해 보겠다.

 

bcrypt

crypto보다 보안이 더 뛰어나고, 사용 문법도 더 간단하다.

Blowfish 암호를 기반으로 설계된 암호화 함수이며 현재까지 사용 중인 가장 강력한 해시 메커니즘 중 하나이다.

반복 횟수를 늘려 연산속도를 늦출 수 있으므로 연산능력이 증가하더라도, brute-forece 공격에 대비할 수 있다.

 

완벽한 보안을 만드는 것은 거의 불가능하기 때문에 보안을 강화하는 것을 많이 생각한다.

bcrypt는 사용이 간편하고, 보안이 뛰어나서 많은 곳에 주로 사용된다.

 

bcrypt 사용법

설치

npm install bcrypt

비밀번호 암호화 하기

const bcrypt = require('bcrypt');
 
const PW = 'abcd1234'
const salt = 12;
 
// async/await 사용
const hash = await bcrypt.hash(PW, salt)

// or

// hash 비동기콜백
bcrypt.hash(PW, salt, (err, encryptedPW) => {
 
})
 
// hashSync 동기
const hash = bcrypt.hashSync(PW, salt);

// hash는 동기, hashSync는 비동기 방식 파라미터로 넣은 숫자 12은 암호화에 사용되는 Salt로, 
// 값이 높을 수록 암호화 연산이 증가하지만 암호화하는데 속도가 느려진다.

비밀번호 검증하기

const PW = 'abcd1234';
const salt = 12;
const hash = bcrypt.hashSync(PW, salt);
 
// async/await
const match = await bcrypt.compare(PW , hash)
if(match) {
	//login
}

// or

// 비동기 콜백
bcrypt.compare(PW , hash, (err, same) => {
  console.log(same);  //=> true
})
 
// 동기
const match = bcrypt.compareSync(PW, hash);
if(match) {
	//login
}

암호화된 비밀번호를 복호하 해서 입력값과 비교할 수 없기 때문에

입력값을 똑같이 암호화 하여 db에 저장된 암호화랑 비교하여 일치 여부를 확인한다.

 

 

 

 

[NODE] 📚 crypto 모듈 (단방향 / 양방향) 암호화 원리 & 사용법

암호화 종류 암호화를 하는 이유는 해당 정보가 중요하기 때문이다. 암호화에는 여러가지 방법이 있을 수 있다. 대표적으로 단반향과 양방향 암호 방식이 있는데, 단방향은 암호화할 수는 있어

inpa.tistory.com

 

[NODE] 📚 bcrypt 모듈 암호화 원리 & 사용법

암호화 종류 SHA-2(Secure Hash Algorithm 2) 미국 NSA에서 설계한 암호화 해시 함수. digest size는 224, 256, 512 bit로 해시함수로 구성되어졌음. GPU를 이용한 연산속도가 매우 빠르기 때문에 password 암호..

inpa.tistory.com

 

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

페이지네이션  (0) 2022.08.23
express HTTPS 설정  (0) 2022.08.20
swagger 설치 및 설정 기본 사용법  (0) 2022.08.17
CORS 사용방법  (0) 2022.08.14
Sequelize 시작, migrate 사용 관계 설정  (0) 2022.08.13