bcrypt

이재문·2021년 11월 28일
0
post-thumbnail

암호화

나는 회원가입 페이지를 구현하기 위해 비밀번호 암호화가 필요하다.
암호화에는 단방향 암호화양방향 암호화가 있다.
암호화된 데이터가 복호화(사람이 해석가능한)가 불가능한 단방향인 해시(hash)와 메세지 인증코드(MAC)가 있고,
암호화된 데이터가 복호화가 가능한 양방향인 공개키, 대칭키가 있다.

나는 비밀번호를 저장하기 위한 암호화가 필요하므로 단방향 암호화인 해시가 필요하다. 이 과정으로 databases에 있는 비밀번호가 암호화되어 저장되어 보안성을 높여준다.

하지만 hashing은 원래 암호화를 하기 위해 설계 된 것이 아니기에 취약점이 있다.
이 취약점을 보완 해 주기 위해 Salting 과 Key Stretching을 해 준다.

  • Salting - 실제 비밀번호 이외에 추가적으로 랜덤 데이터를 더해서 해시값을 계산하는 방법.
  • Stretching - 단방향 해쉬값을 계산 한 후 그 해쉬값을 또 해쉬 하고, 또 이를 반복하는 것을 말한다

Hashing, Salting와 Stretching를 한번에 할 수 있는 bcrypt가 있다.

bcrypt의 구성

bcrypt의 구성은 아래와 같다

$2b$[cost]$[22 character salt][31 character hash]

$2a$09$QsdkQf2Ack8lAkd9Ask8kcfl7p92ldGxad68LJ1ZaAk4AcL17lhWy
 \/ \/ \____________________/\_____________________________/
Alg Cost       Salt                        Hash

2a: 해시 알고리즘 식별자
10: Cost
QsdkQf2Ack8lAkd9Ask8kc: 솔트, base64-encoded to 22 characters
fl7p92ldGxad68LJ1ZaAk4AcL17lhWy: 해시, base64-encoded to 31 characters

bcrypt 암호화 방법

bcrypt.hashpw() : Hashing 하는 방법
bcrypt.gensalt() : Salting 하는 방법

password = 'abcd'
hashed_password = bcrypt.hashpw(password, bcrypt.gensalt())
>>> TypeError: Unicode-objects must be encoded before hashing

hashing과 salting을 하기 위해 작성하였지만 컴퓨터가 이해 할 수 있도록 인코딩을 진행하지 않아 에러가 발생했다.
password.encoding('utf-8') 로 인코딩하여 hashing과 salting을 진행하면 에러가 발생하지 않고 정상적으로 암호화가 완료된다.

password = 'abcd'
bcrypt.hashpw(password.encode('utf-8'), bcrypt.gensalt())
>>> b'$2b$12$WJ2d1UMwjMVkAy6gFgxveu.58pBwd8lzEwJ60IsHYnckzBgiLIi7S'

이때 암호화된 문자의 type()<class 'bytes'>가 된다.
암호화가 완료되어 비밀번호가 생성되었지만 비밀번호를 저장할 때는 password를 str값으로 저장되어야 매칭이 가능하므로 다시 decode를 진행한다.

bcrypt.checkpw() : 입력된 비밀번호와 DB에 저장된 저장된 값이 일치한지 확인하기 위한 함수이다.

bcrypt.checkpw(입력받은 PW.encode('utf-8'),저장된PW의위치.password.encode('utf-8')):
>>> return True
profile
이제부터 백엔드 개발자

0개의 댓글