TIL #45 HTTP : Bcrypt & Pyjwt

6998 단어 TILwebTIL

bcrypt & pyjwt




- bcrypt

conda activate westargram17
pip install bcrypt

먼저 기존에 계속 사용했던 가상환경에 bcrypt를 설치한다.

bcrypt ??
단방향 암호화에 사용되는 라이브러리이다. python 외에도 javascript 등 다양한 언어를 지원한다.
알고리즘을 개인적으로 짜려면 짜겠지만... (지금의 나는 불가능) 민감한 사항이므로 정교하게 만들어진 라이브러리를 사용하는걸 추천한다.



- views.py


암호화 과정

1. import bcrypt
python 의 라이브러리 이기 때문에 from ~~ 을 하지 않고 바로 import 해준다.

2. hash_password
문자열로 입력받은 password를 암호화 한다.
bcrypt.hashpw(password.encdode('utf-8'), bcrypt.gensalt())

  • bcrypt 는 byte 타입만 가능하다
  • bcrypt.hashpw(byte 타입으로 변환한 password, salting+keystretching하기)
  • salt는 임의의 byte 타입 문자열이다. salt의 결과는 매번 다르다.
>>> bcrypt.gensalt()
b'$2b$12$w1QLz8Ra4SnBHIXyod2Qe.'

>>> bcrypt.gensalt()
b'$2b$12$ihvaqiGC1hLJEl3GqaWWAe'
b
>>> bcrypt.gensalt()
b'$2b$12$OUjwGEAgw1JQUsNXnIYt0u'
  • salting 한 값은 byte타입으로 변환된 입력한 password의 에 위치한다.
>>> salt = b'$2b$12$OUjwGEAgw1JQUsNXnIYt0u'
>>> password = '123'
>>> hash_password = bcrypt.hashpw(password.encode('utf-8'), salt)
>>> hash_password
b'$2b$12$OUjwGEAgw1JQUsNXnIYt0udDEBLWJ8jKlnSZ8/Z97tzpgKNSCI4KG'

3. create
hash_password는 byte 타입인 반면에 models.py에 저장되는 password의 형태는 CharField이다. 때문에 encode과정을 통해 byte 타입화 된 형태가 저장된다면
b'$2b$12$OUjwGEAgw1JQUsNXnIYt0u'b'까지 문자열로 인식하게 되어 이후 제대로 된 비교가 불가능하다. 때문에 두가지 방법 중 하나를 선택해야 한다.

  1. models.py에서 password를 CharField가 아닌 BinaryField 로 바꿔준다.
  2. 암호화 된 password (hash_password)를 다시 decode('utf-8')하여 db에 저장시킨다.

나의 경우 2번을 선택하였다. (models.py 변경하는 것에 대한...큰..두려움...)


데이터 집어넣은 나 조차 어떤 비밀번호인지 모른다.. 보안 굿!?


- pyjwt

pip install pyjwt

jwt : 인증을 위한 수단인 JSON Web Token


views.py


인가 과정

1. import jwt
install 할때는 pyjwt 이지만 import 이름은 jwt 이다.

2. bcrypt.checkpw
bcrypt에서 제공하는 checkpw 함수이다.
checkpw(검사하고자 하는 대상, 검사 대상) 을 입력하는 데 이 함수는 꼭 byte 타입만 검사 가능하다! 때문에 str type이라면 .encode('utf-8')을 해주어야 한다.

bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8))

만약 두가지가 같다면 True를 / 두가지가 다르다면 False를 반환한다. 때문에 위 결과를 사용해 적절한 response를 줄 수 있다.

if not bcrypt.checkpw(password.encode('utf-8'), user.password.encode('utf-8))

만약 두가지가 같다면 True, not과 만나서 최종 False 이다.
만약 두가지가 다르다면 False, not과 만나서 최종 True로 INVALID_USER를 반환하게 한다.

3. SECRET_KEY
token을 발행하는데 사용되는 임의의 배열이다. 이때 사용되는 SECRET_KEY (예명)는 django project 생성시 배정된 django.conf의 settings.py 에 있는 SECRET 번호여도 되지만, 새로 작성하여도 된다. 단, 공개 금지!!!!

4. access_token
import 했던 jwt의 함수를 사용한다.

encode({'user' : user.id}, SECRET_KEY, algorithm='HS256')

jwt의 구조에서 header와 body에는 절.대.로 user의 개인 정보를 담아서는 안된다. (금방 털림) 때문에 user의 id값을 제공한다. (db에 대한 접근 권한이 없다면 id 만 알아도 아무 쓸데 없다.)
또한 algorithm또한 어떤걸 사용했는지 알려주면 안된다. 때문에 'HS256'을 담은 변수를 다른 파일에 저장시켜 import 하는것이 좋다.


좋은 웹페이지 즐겨찾기