TIL #45 HTTP : Bcrypt & Pyjwt
bcrypt & pyjwt
- bcrypt
conda activate westargram17
pip install 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'
까지 문자열로 인식하게 되어 이후 제대로 된 비교가 불가능하다. 때문에 두가지 방법 중 하나를 선택해야 한다.
- models.py에서 password를 CharField가 아닌 BinaryField 로 바꿔준다.
- 암호화 된 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 하는것이 좋다.
Author And Source
이 문제에 관하여(TIL #45 HTTP : Bcrypt & Pyjwt), 우리는 이곳에서 더 많은 자료를 발견하고 링크를 클릭하여 보았다 https://velog.io/@c_hyun403/HTTP-BcryptPyjwt저자 귀속: 원작자 정보가 원작자 URL에 포함되어 있으며 저작권은 원작자 소유입니다.
우수한 개발자 콘텐츠 발견에 전념 (Collection and Share based on the CC Protocol.)