Django 의 인증, 인가, 암호화,토큰

김병욱·2020년 6월 25일
0

Django

목록 보기
12/15

출처

장고의 인증 인가

장고의 인증 인가

예를 들어 회원가입 또는 로그인시에는 무조건 패스워드나 개인정보가 암호화되야한다.
정보를 은닉하고, 특정 페이지는 인증된 사용자만 볼 수 있게끔 해야한다.
마이페이지 같은 페이지에서는 회원정보 수정등을 해야하고 회원만 볼 수있는 게시판등이 대표적이다.

인증

유저의 아이디나 패스워드를 확인하는 절차이다.
인증을 위해 유저의 아이디와 패스워드를 생설할 수 있는 기능도 필요로하다.

로그인의 절차

1.유저 아이디와 패스워드를 생성 (회원이 아니라면)
2.유저 패스워드 단반향 해시 암호화 (해당 패스워드 db에 저장함)
3.유저 아이디,패스워드 입력
4.유저 아이디를 찾았다면, 입력한 패스워드와 db에 암호화되어 저장된 패스워드를 비교한다
5.입력된 패스워드가 db의 암호화된 패스워드와 동일하면 로그인
6.로그인 성공시 access token을 클라이언트에게 전송
7.로그인 성공시 access token을 들고 request를 웹서버를 전송하면서 매번 로그인을 하지 않아도 서비스를 이용할 수 있게 한다.

비밀번호 관리법

  • 법률 상 비밀번호와 주민등록번호 등의 고유한 개인정보는 암호화 보안 절차를 통해 전송되어야한다.

  • 국가에서 권고하는 암호화 알고리즘을 통해 개인정보를 암호화하고, db에 저장할때에는 개인정보를 해싱하여 복원할 수 없도록 한다.

  • 개인정보를 주고받을때 통신시 SSL을 적용하여 암호화한다(HTTPS).

비밀번호 암호화

비밀번호는 관련되지 않는 사용자를 제외하고는 해당 서비스 개발자도 쉽게 볼 수 있으면 안된다. 따라서 단방향 해쉬 함수 기반의 단반향 알고리즘을 적용하여 암호화가 되어 저장되는 순간 이후에는 원래 비밀번호를 알 수 없게 (사용자만 알 수 있게) 처리해야된다.

  • 단반향 해쉬함수(MD5, SHA-1, SHA-256)이 일반적으로 사용된다.
  • 해쉬함수는 원래 자료구조에서의 빠른 자료 검색, 데이터의 위변조 체크를 위해 사용되지만, 복원이 불가능한 단방향 해쉬함수는 암호학적으로 사용된다.
  • 단반향 해쉬함수는 원본 메세지를 변환하여 암호화된 메세지 (다이제스트)를 생성한다

단방향 해쉬함수는 몇가지 취약점이 존재한다. 대표적으로 rainbow table attack (rainbow table : 미리 해쉬값들을 계산해놓은 테이블) 등과 같은 공격에 매우 취약하다. 해쉬함수의 본래 목적은 데이터에 빠르게 접근하기 위해 설계되었다. 대표적으로 파이썬의 딕셔너리형과 set형이 해쉬를 기반으로 만들어진 자료형이다. 이렇게 빠른 접근성이 1:1로 빠르게 접근이 가능하다면 임의의 문자열 다이제스트(해쉬로 암호화된 메세지)와 해킹할 대상의 다이제스트를 비교할 수 있다. 비밀번호과 단순하거나 길지 않다면 취약점이 될 수 있다. 하지만 이를 해결하기위해 두가지의 보완점이 있다.

  • salting : 소금을 치는것 처럼 해결하는 방식이다. 실제로 숨길 비밀번호 이외에 랜덤한 더미 값들이 더해져 해쉬값들을 계산하는 방법으로 실제 어느 부분이 진짜 비밀번호이고 어느부분이 더미 값들인지 알 수 없게 만드는 방법이다. rainbow table attack을 무력화 시킬 수 있다.

  • key stretching : 해쉬함수의 빠른 실행속도에 따른 취약점을 보완하기위해 단방향 해쉬값을 계산하고 그 해쉬 값의 해쉬값을 계산하여 여러번 반복하는 방식이다. 1초에 50억개 이상의 다이제스트를 비교할 수 있는 부분에서 해당 방식을 적용하면 동일한 장비에서 1초에 5번정도만 비교할 수 있게 할 정도로 공격에 따른 속도를 늦출 수 있다. 그래서 이론적으로는 정보를 탈취할 수 없지만 소요시간을 길게 하는 방식이라고 볼 수 있다.

파이썬에서의 단방향 해쉬함수 중 위 두가지 보완점이 적용된 패키지로 bcrypt가 존재한다. 실제 웹개발 시 많이 사용되는 암호화 패키지이다.

비밀번호 암호화 방법

  • mac os terminal
    pip install bcrypt

장고 프로젝트 manage.py shell에 들어가서 실습해보자.

import bcrypt #암호화 패키지 임포트
pw = '1234'
pw_hash = bcrypt.hashpw(pw.encode('utf-8'),bcrypt.gensalt()) #pw변수에 담긴 비밀번호를
해싱한다
#해싱할 비밀번호는 항상 encode로 utf-8(유니코드)로 인코딩 해주어야 한다.
pw_hash = pw_hash.decode('utf-8')
#db에 저장할 수 있는 유니코드형태로 디코딩한다

비밀번호와 암호화된 다이제스트 비교

bcrypt.checkpw(pw.encode('utf-8'),pw_bcrypt)
#pw변수와 해싱된 비밀번호가 담긴 pw_bcrypt변수가 같은지 bool형으로 반환한다

인가

  • 클라이언트의 요청에 대해 실행할 수 있는 권한이 있는지 없는지를 확인하는 절차이다.
  • 로그인의 유무등의 기능들.. 세션과 비슷하다
  • 인가의 기능을 제대로 못한다면 각 페이지별 보안기준이 모호해지거나 인증이 필요한 페이지별로 매번 로그인해된다는 등의 귀찮음이 생긴다.
  • 서버측에 클라이언트의 세션정보를 메모리, 디스크, db등을 저장을 하는 서버기반 인증/인가 가 있고, 리소스 및 효율을 개선해서 나온 token 기반의 인가방식이 있다. access token 을 사용한 인가 방식들 중 대표적으로 JWT(JSON Web Token) 방식이 주로 쓰인다. (access token 을 통해 해당 클라이언트가 누군지 알 수 있으므로 해당 유저의 퍼미션도 확인이 가능하다)

access token을 통한 인가의 절차

1.Authenticatioon 절차를 통해 (로그인) access token을 생성함. access token에는 클라이언트의 정보를 확인할 수 있는 정보가 들어감.
2.클라이언트가 request를 보낼 때는 access token을 첨부해서 보낸다(Front-end/Client)
3.서버에서는 클라이언트가 보낸 access token의 내용을 복호화(디코딩)한다.
4.복호화된 데이터를 통해 user id나 user의 정보를 식별할 수 있는 데이터를 얻는다.
5.user id를 사용해 DB에서 해당 유저의 퍼미션을 확인한다.
6.해당 요청에 대한 퍼미션을 가지고 있는 user라면 해당 요청을 처리한다.
7.권한이 없는 user라면 401에러 등으로 응답한다.

  • access token 을 사용하는 이유
    1. 매번 id, pw에 대한 해싱 값과 비교하기보다 저장할 필요없이 user 식별 정보를 해싱하여 인가만 하면 된다.
    1. 실제 id, pw가 쿠키상에 저장되지 않고 특정 서버에 특화되어 있기 때문에 다른 서버에서 재사용될 수 없다.

JWT (JSON Web Token)

토큰 기반의 인증 방식중 HTTP Authorization header나 URI query parameter등 공백을 사용할 수 있는 곳에서 사용되는 JSON 객체 방식의 토큰이다. 다시말해 JWT는 유저의 인증 정보를 JSON형식으로 담고 암호화를 하여 인증이 필요한 서비스를 사용할 시 HTTP header를 통해 서버와 클라이언트간에 JWT만 무사히 주고 받아도 특정 인가가 필요한 서비스를 지속적으로 이용하게 해준다.

JWT 사용법

우선 장고 프로젝트내 settings.py에 SECRET_KEY 변수를 변경/분리 하는 방법을 참조하자.
SECRET_KEY 변경/분리 링크

  • mac os terminal
    pip install PyJWT

장고 프로젝트의 manage.py shell에 들어가서 실습해보자.

import jwt
from 프로젝트명.settings import SECRET_KEY
id = 'kbu'
token = jwt.encode({'user_id':id},SECRET_KEY,algorithm='HS256')
#HS256 함수로 토큰을 발행한다
token.decode('utf-8')
#토큰을 디코딩한다

profile
개발스터디

0개의 댓글