본문 바로가기

Web

Auth

전체적인 인증, 인가는 프론트와 백엔드 간의 상호 작용이다.

사용자의 권한에 따라 접근할 수 있는 영역이 달라질 때 인증 인가가 필요하다.

파이썬 기반 백엔드에서 구현하는데 bcrypt, pyjwt를 사용했다.

인증 Authentication

사용자 입장 - 내가 나임을 증명하는 과정

개발자 입장 - 회원가입, 로그인

 

비밀번호 암호화는 법규상의 강제이다.

복원할 수 없게 암호화한 뒤 저장해야 된다. HTTP 통신시에는 SSL을 적용하여 암호화해야 정보를 보호할 수 있다.

SSL

SSL은 전자상거래보안을 위해 개발한 암호화 방식이고 웹 서버와 브라우저간 보안 통신 규약(프로토콜)이다. 참고 링크

HTTP의 보안 강화 버전인 HTTPS 프로토콜이 SSL 상에서 돌아간다.

 

1. 인증기관이 사이트의 정보를 검토하고 이 정보와 사이트의 공개키를 인증기관의 비밀키로 암호화하고 사이트로 회신한다.

2. 개인이 브라우저를 통해 사이트에 접속하면 사이트로부터 이를 받는다.

3. 브라우저는 인증기관의 공개키를 가지고 있다. 이걸로 받은 걸 복호화해서 사이트의 공개키를 얻는다.

4. 브라우저가 사이트의 공개키로 대칭키를 암호화해서 사이트로 보낸다.

5. 사이트는 이를 사이트의 개인키로 복호화한다.

그 뒤엔 개인-사이트가 대칭키로 통신할 수 있다.

 

+ 데이터를 보안하는 것을 중요하게 생각할 때 공개키로 암호화하고,

인증 과정을 중심으로 생각할 때 개인키로 암호화(공개키로 복호화)한다.

 

생활코딩 SSL 강의에서 예시로 든 startssl은 이제 사용할 수 없고, 대신 참고 링크를 보고 SSC를 생성해보는 실습을 할 수 있겠다.

암호화 방식

해쉬함수에 입력값을 넣으면 알고리즘을 거쳐 입력값과 다른 별개의 결과값이 나온다. 하지만 같은 알고리즘으로 동일한 입력값을 넣으면 항상 결과가 같다. 단방향 해쉬함수는 원칙적으론 복원이 불가능하지만 이 점을 이용해서 가능한 경우의 수를 모두 해시값으로 만들어 둔 Rainbow table을 이용해 원본을 유추할 수도 있다.

그래서 비밀번호를 맞추기 어렵게, 유추 시도가 오래 걸리게 만들어야 된다. 여러 사용자가 같은 비번을 사용한다 하더라도 서로 유추하기 어렵게 해쉬 후의 결과를 다르게 만들어야 된다. 이렇게 할 수 있게 하는 방법으로 salting과 key stretching이 있다.

salting

랜덤한 문자열을 원본에 붙이고 hashing하면 원본이 같더라도 다른 결과값을 얻을 수 있다.

key stretching

salting 및 hashing을 여러번 반복해 길이를 늘린다. salt는 저장되어 있고, hashing을 반복할 때 계속 같은 salt를 붙인다. 이 salt가 노출이 되어있더라도 원본을 모르니 유추해 해킹하는 데 오래 걸리게 할 수 있다.

 

salting과 key stretching을 편하게 해주는 라이브러리 bcrypt. 결과값에 반복횟수, salt와 hash된 이후의 값을 같이 보관하기 때문에 DB 설계를 복잡하게 할 필요가 없다.

알고리즘으로는 대개 SHA256을 사용한다. MD5, SHA-1은 오랫동안 사용하다보니 많이 밝혀져서 이젠 안 쓰는 알고리즘이다.

 

cf. 양방향 해쉬함수로 암호화한 건 복원할 수 있다

DB에 암호화해서 저장해야되긴 하지만 다시 복구해서 써야되는 정보를 이렇게 암호화 한다.

e.g. 주민등록번호, 신용카드번호

이메일, 아이디는 대개 암호화까지 하진 않는다.


인가 Authorization

사용자가 로그인하면 해당 사용자가 맞는지 확인하는 과정.

사용자가 요청하는 request를 실행할 수 있는 권한이 있는 유저인가를 확인하는 절차.

 

HTTP는 stateless한 성질이 있기 때문에 로그인 이후 요청이 같은 사용자에게서 온 건지 모른다.

 

처음 로그인에 성공한 뒤 서버에서  이런 방식으로 로그인 유지를 함.

 

그래서 처음 로그인에 성공한 뒤 서버에서 access token을 발급, 응답에 담아 클라이언트에게 전송하고, 사용자는 그 후 요청을 보낼 때 아이디와 비밀번호 재입력 대신 access token을 첨부한다. 이 토큰을 쿠키에 저장할지 웹스토리지에 저장할지는 어떤 기능을 위해서인지에 달려있어서 프론트가 정해줘야 된다.

이 요청의 headers에 넣는 메타데이터가 JWT(JSON Web Token)이다.

JWT

headers, payload, signature 이렇게 3개로 나뉜 구조다.

headers - 사용한 알고리즘, 타입 정보(JWT)가 들어있다.

payload - 사용자가 누군지와 토큰의 유효기간이 들어있다. 이 '누군지'에 대한 정보는 누군지는 명확하되 제3자가 보면 정확히 누군지는 알 수 없는 정보여야 한다. 그래서 대개 DB 내의 user_id 같은 걸 사용한다. 유효기간은 5분, 2주 등 여러 종류이다.

signature - 이 부분을 복호화해서 해당 서버에서 생성한 JWT가 맞는지 확인한다.

 

headers와 payload는 BASE64 방식으로 인코딩해 복호화가 쉽고, signature은 암호화되어있다. 따라서 보안이 취약한 payload에는 사용자의 개인 정보를 담지 말아야 한다.

'Web' 카테고리의 다른 글

RESTful API  (0) 2021.03.01
Style We 프로젝트 이미지 2  (0) 2021.02.24
Style We 프로젝트 이미지 1  (0) 2021.02.24
How the Web works  (0) 2021.01.22
개발자 도구 - Application panel  (0) 2021.01.15