bcrypt & PyJWT

이산·2022년 3월 23일
0

기술블로그

목록 보기
14/42

인증 및 인가

인증이란 참이라는 근거가 있는 무엇인가를 확인하거나 확증하는 행위이고 이를 통해서 누가 우리 서비스를 어떻게 사용하고 있는지 추적할 수 있다. 쉽게 말하면 유저의 ID나 Password를 확인하는 절차이다.

인가란 무엇인가의 허가를 받는 행위이고 유저가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차이다.
로그인을 통해서 ID와 Password를 확인하여 인증을 받고 암호화된 비밀번호와 토큰으로 해당 유저의 권한을 확인하는 것이 인가의 절차이다.


암호화

내가 아닌 다른 사람이 나의 정보를 갈취할 수 없도록 보호하기 위해 필요하다. 개인정보를 암호화 하도록 법률에서도 규정하고 있다. 그렇기 때문에 서비스를 운영할 경우에 정보의 암호화는 필수이다.


Hash

본래 해쉬는 자료구조에서 빠른 자료의 검색, 데이터의 위변조 체크를 위해 쓰이지만 단방향 해쉬는 복원이 볼가능하기 때문에 암호화적 용도로 사용한다.임의의 길이의 데이터를 고정된 길이의 데이터로 매핑(해당 값이 다른 값을 가르키도록 하는 것)하는 함수이다. 아무리 큰 값이 나와도 정애진 크키 안에서 결과가 나오며 이렇게 나온 고정된 길이의 값을 해시값이라고 한다. 복잡하지 않은 알고리즘으로 구현되기 때문에, 상대적으로 CPU, 메모리 같은 자원을 덜 소모하는 특성이 있다. 보통 입력 값보다 출력 값이 작은 경우가 많기 때문에 드물게 동일한 값이 출력되는 경우가 있고 이러한 경우를 ‘충돌’ 이라고 한다.

매핑 전 원래 데이터 값 : 키(Key)

매핑 후 데이터 값 : 해시 값(hash value)

매핑하는 과정 : 해싱(hashing)


bcrypt(비크립트)

Blowfish 암호를 기반으로 설계된 암호화 함수이며 현재까지 사용중인 가장 강력한 해쉬 매커니즘 중 하나이다. salting과 key stretching 개념을 사용한 대표적인 라이브러리다. 다양한 언어를 지원하고 있으며 구현이 쉽고 비교적 강력하다. salting을 자동으로 진행해주기 때문에 편리하다.

salting - 입력한 비밀번호와 임의로 입력한 문자열(salt)를 합쳐서 해싱해서 해시값을 저장하는 방법이다. 이때, 비교를 위해 해시값과 salt값을 같이 저장해야 한다.

key stretching - 해커가 패스워드 무작위 대입을 통해 해시값을 계산하는데 걸리는 시간을 대폭 늘리기 위해 salting 및 해싱을 여러번 반복해서 원본 값을 유추하기 어렵게 하는 방법이다.

해싱된 값의 구조

bcrypt를 이용하여 암호화하기

  • pip install bcrypt
  • import bcrypt!

str을 encode 하면 bytes(이진화)가 되고, bytes를 decode 하면 str이 된다.

위와 같이 작성하여 암호화 된 비밀번호를 얻을 수 있다.

bcrypt의 checkpw 기능을 통해서 해당 비밀번호가 맞는지 확인할 수 있다.

checkpw는 checkpw(사용자로부터 입력받은 패스워드, 저장된 암호화된 패스워드) 이며 둘 다 데이터 타입은 bytes이여야 한다.


JWT

서버와 사용자 사이에 정보를 주고 받을 때, http request 헤더에 메타데이터를 보내는데 이러한 메타정보를 JWT(JSON Web Token)이라고 한다. 토큰을 받으면 사용자는 헤더에 포함되어 있는 JWT 정보를 통해 인증하고 로그인 상태로 서비스를 돌아다닐 수 있다.

클라이언트와 서버, 서비스와 서비스 사이 통신 시 권한인가(Authorization)를 위해 사용하는 토큰

JWT 구조

인코딩

암호화라기 보다는 다른 언어로 번역해주는 기능이다. header와 payload는 암호화 한 것이 아니므로 개인정보를 담아서는 안된다.

헤더(header)

  • 토큰의 타입과 해쉬알고리즘(어떤 해싱 함수를 사용할 것인지) 정보가 들어간다.
  • 헤더의 내용은 base64 방식으로 인코딩해서 JWT 맨 처음에 입력한다.

내용(payload)

  • 만료시간 같이 미리 정의된 내용, 공개용 정보 전달을 목적으로 하는 내용, 클라이언트와 서버간 합의하여 사용하는 private 내용을 base64 방식으로 인코딩하여 저장한다.
  • 이러한 하나하나의 정보들을 claim 이라고 하며 총 3개의 claim이 저장된다.
  • 키 벨류 형태로 어떤 고유의 값을 넣어줄 것인지가 중요하다.

서명(signature)

  • base64URL로 인코딩된 header와 payload, JWT SECRET_KEY를 헤더에 지정되었던 해쉬 알고리즘을 이용해서 암호화한다.
  • 프론트엔드가 JWT를 백엔드 API로 전송하면 서버에서는 서명(signature)내용을 복호화하여 서버에서 생성한 JWT가 맞는지 확인한다.

JWT로 토큰 생성하기

  • pip install PyJWT
  • import jwt

위에는 ID가 1인 토큰을 생성했다. 이를 통해서 유저를 식별할 수 있다.

profile
백엔드 개발자입니다.

0개의 댓글