유저 정보를 암호화해보자 (feat. Bcrypt)

1

공통

목록 보기
5/9
post-thumbnail
post-custom-banner

출처 :

🤔 Bcrypt란?

1999년에 Niels Provos와 David Mazieres가 발표한 가장 강력한 단방향 비밀번호 해시 매커니즘 중 하나이다. C, C++, C#, Go, Java, PHP, Perl, Python, Ruby등의 언어를 지원한다.

Keypoint = 단방향 해시 함수 !

단방향 해시 함수라는 것은 원본 메세지를 Hash Algorithm으로 암호화하여 다시 평문으로 볼 수 없는 "digest"를 생성한다.

Bcrypt의 단점

  1. 동일한 메세지가 동일한 digest을 생성하기 때문에 따로 Hash Algorithm별로 비밀번호에 대한 테이블을 준비하여 해당 알고리즘이 무엇인지, 사용자의 비밀번호가 무엇인지 역추적이 가능하다. 이런 공격을 rainbow 공격이라고 한다.

  2. 해쉬 함수는 사실 짧은 시간에 데이터를 검색하기 위해 설계되어 처리속도가 빠르다. 하지만, 이것은 오히려 단점이 될 수 있는데, 해커가 대량의 hash된 비밀번호를 준비하고 빠른속도를 이용하여 원래의 비밀번호를 비교 후 해킹할 수 있다.

솔팅 & 키 스트레칭

위와 같은 단점을 보완하기 위해, 해쉬 함수에 솔팅과 키 스트레칭이라는 기법을 덧붙였다.

솔팅

해쉬되기 전 원본 비밀번호에 추가적인 길이의 문자열을 생성하여 암호화된 digest를 생성하는 기법이다. 일방적으로 모든 비밀번호가 랜덤한 고유의 솔트값을 가지고 있고, 솔트값의 길이는 32바이트 이상이기 때문에 원본 비밀번호를 알아내는 것도 더 어려워지지만, 비밀번호를 알아내더라도 salt와 원본 비밀번호를 또 비교해야 되기 때문에 해킹이 더 어려워진다.

키스트레칭

입력된 비밀번호로 digest를 생성하고, 그 digest된 비밀번호를 다시 hash해서 digest를 생성하는 기법이다. 원본 비밀번호를 알아내기 위해서는 해당 digest된 만큼 hash해야지만 비밀번호를 알아낼 수 있기 때문에 위에서 말한 2번 단점을 보완할 수 있다.

위의 사진은 프로젝트때 만든 가짜 사용자 데이터인데, 앞 부분에서 공통적인 부분을 확인할 수 있다.

  • $2b 라는 것은 bcrypt 버전 정보이다.
  • $12는 키스트레칭을 돌린 횟수를 나타내며 12는 2의 12승만큼을 나타낸다.
  • 그 뒤로는 솔팅된 비밀번호가 해쉬된 text이다.

🖊️ 실제로 적용해보자 (Python 버젼)

Step 1 : 설치

먼저 프로젝트 가상환경에서 bcrypt 모듈을 설치하자

$ pip install bcrypt

만약, Debian과 우분투 유저라면 아래의 커맨드를 입력하여, 필요한 dependency를 설치하도록 하자

$ sudo apt-get install build-essential libffi-dev python-dev

다른 OS환경은 아래의 링크를 참고해주세요.

Step 2 : 암호화하여 저장

import bcrypt

...

hashed_password = bcrypt.hashpw([유저 패스워드 텍스트].encode('utf-8'),bcrypt.gensalt())

...

password = hashed_password.decode()

위와 같이 bcrypt를 먼저 import 한 다음 유저의 패스워드 정보를 'utf-8'로 binary로 만든다음 해당 데이터에 솔팅을 해주는 bcrypt.gensalt() Method 로 해쉬해주면, 아래와 같은 암호화된 비밀번호를 확인 할 수 있다. 하지만, encode된 binary text는 mysql DB에 들어갈 수 없기때문에, encoding을 풀어주고 넣어줘야된다.

Step 3 : 암호화된 정보 비교

bcrypt 모듈에는 해당 해쉬된 digest와 plain text를 비교할 수 있는 checkpw()라는 메소드가 있다. 아래와 같이 데이터를 비교하여 DB에 있는 유저 비밀번호와 입력된 비밀번호를 비교하여, True or False를 반환한다.

bcrypt.checkpw([입력된 비밀번호].encode(),[해쉬되어 저장된 비밀번호].encode())

🔐 암호화를 해야되는 이유 !

적다보니 왜 암호화를 해야되는지 설명을 안한것 같아서 늦게나마 적지만, 일반적으로 DB가 해킹당할 수 있다는 위험요소가 존재하기 때문이라고 생각한다. 뉴스를 보면 가끔씩 대규모 서비스에서 조차도 유저의 민감한 개인정보가 해킹되는 사건을 확인할 것이다. 그렇기 때문에, 이런 암호화도 안한다면 너무나도 사용하기 불안한 서비스이기 때문에 유저의 UX며 법적으로도 문제가 많이 발생할 것이다. p.s. 애초에 개발자가 직접적으로 유저의 비밀번호를 확인하는 것은 법적으로 금지되어있다.

끝 🌈

profile
# 개발 # 컴퓨터공학
post-custom-banner

0개의 댓글