인증 & 인가

박은정·2021년 8월 25일
0

TIL

목록 보기
18/72
post-custom-banner

인증

내가 나라는 것을 증명한다
웹사이트 상에서 자기자신이라는 것을 증명한다
이를 증명하기 위해서는 
개인정보를 데이터베이스에 저장해서 → 회원가입 & 로그인 기능으로 체크한다
회원을 식별하기 위해서 회원가입 & 로그인 기능을 이용한다
  • 인증 : 회원가입과 로그인
  • 인증이 필요한 이유 : 우리 서비스를 누가 어떻게 쓰는지 추적이 가능하도록 하기위해서
  • 인증에 필요한 것 : 아이디, 이메일주소, 비밀번호

인증에 필요한 것 중에서 비밀번호가 제일 중요하기 때문에 따로 관리를 해줘야 되는데
이와 관련된 법률도 있어서 암호화처리를 해야한다

비밀번호 암호화 과정

1. 해싱

난독화한다

개발자가 비밀번호를 복원해서 채굴할 수 있기 때문에
이런식으로 암호화를 한 개발자도 어떤 문자였는지 확인할 수 없게 해야한다

2. 통신할 때에도 한 번 더 암호화 진행

단순한 텍스트로 전송을 하면 중간에 해킹을 당할 수 있기 때문에
네트워크 통신전송할 때에도 https를 통해 암호화를 한 번 더 한다

https = http + security
이 사이트는 보안된 웹사이트가 아닙니다의 형식으로 경고문구가 나오도록 한다
주소창 왼쪽에 자물쇠 걸려있음

비밀번호 암호화 방법

프론트도 결국엔 자료구조 및 알고리즘을 알아야 한다....!

1. 해쉬

자료구조 중에서 빨리 검색하기 위한 것
하나의 input에는 하나의 output만 있도록

2. 단방향

한 방향으로만 진행가능한 일방통행이다
그래서 input → output 방향으로 값을 찾을 수 있지만
output → input 의 방향으로는 찾을 수 없다

따라서 단방향 해쉬를 하면 암호화는 가능하지만 복호화는 못한다
그래서 비밀번호를 잃어버렸을 때, 찾지는 못해서 다시 임시비밀번호를 발급해준다

레인보우 테이블

output으로는 알 수 없는 값으로 항상 동일하게 나오기 때문에
이러한 허점을 이용해서 노가다코딩을 통해 해쉬값을 구할 수 있는 데이터베이스를 구할 수 있다
이러한 데이터베이스를 구하는 서비스를 레인보우 테이블이라고 한다

3. Salting & Key Skertching

이러한 허점을 보완하기 위해 Salting과 Key Skertching 이라는 기술이 생겼는데
이는, 비밀번호와 임의로 생성한 문자열 (Salt)를 합쳐서 해싱하고 이 해싱값을 저장하는 방법이다

키 스트랫칭 (Key Skertching)

해커가 비밀번호 무작위 대입을 통해 해시값을 계산하는데 필요한 시간을 대폭 늘리기 위해 Salting 및 해싱을 여러번 반복해서 원본 값을 유추하기 어렵게 만드는 것이다
절대로!! 해킹할 수없게 차단하는 것이 아니라 암호화를 뚫을 수 있긴 한데 솔트값이 없는 것보다는 더 오랜 시간이 필요해서 그 사이에 데이터베이스가 노출되었다고 알람이 나오고 사용자가 비밀번호를 바꿀 수 있게 도와주는 것이다
한 마디로 사용자가 비밀번호를 변경할 수 있도록 시간을 끄는 것이라고 할 수 았다

단순 해싱값을 극복하기 위해 랜덤한 문자열을 넣고 지정된 알고리즘을 통해 해싱값을 만든다
이러한 알고리즘은 수학자들이 만들고 우리는 가져다 쓰기만 한다 (직접 알고리즘을 만들려고 하면 너무 힘들다)

예) 1234 -> 비건 1234 -> 이 값을 해싱해서 asdfgasdf
비밀번호 + 임의 문자 = 해싱값
비밀번호 + 솔트값 -> 암호화된 해싱값
// 1솔2트3값4 이렇게는 안한다 
최종적으로 저장된 거는 솔트값asdfgasdf

이런 방식으로 원래의 비밀번호를 찾을 수 없게 만드는데
물론 이때에도 비교를 하기 위해
원래 사용자가 입력한 비밀번호 1234 + 솔트값인 "비건" 도 같이 저장한다

4. 비크립트 bcrypt

  1. 앞서 말한 Salting & Key Skertching을 실제로 적용하기 편하게 해주는 대표적인 라이브러리
  2. 다양한 언어를 지원하고 있으며, 사용이 간편하여 쉽게 적용이 가능하다
  3. bcrypt는 해쉬값(=hash 결과값)에 소금값과 해시값 및 반복횟수를 같이 보관하기 때문에
    → 비밀번호 해싱을 적용하는데에 있어서 DB 설계를 복잡하게 할 필요가 없다
  4. bcrypt를 통해 → 해싱된 결과 값 (Digest)의 구조는 아래 사진이라고 말할 수 있다


인가 Authorization

사용자가 로그인을 했을 때 http의 stateless 의 특징이 있어서
→ 서버가 클라이언트에게 header요소에 메타데이터 (=토큰)을 보내주고
→ 클라이언트가 로그인이 필요할 때마다 쿠키를 통해 토큰을 사용하도록 하는 것이다

HTTP 특징 예시
요청 1 : zoom 로그인
응답 1 : 로그인 200 OK! (+Token 발행)

요청 2 : meeting 접속 (+ 발행받은 토큰과 함께 요청을 보낸다)
응답 2 : meeting 접속 OK!

토큰

JWT : JSON Web Token
서버가 클라이언트에게 header요소에 보내는 사용자의 인가에 대한 메타정보
https 인증할 때 stateless를 보완하기 위한 토큰이다
인가의 과정에서 사용자의 신원을 확인하고 해당 요청이 유효하도록 허가증을 보내주는 것이다
서버에 사용자에 대한 정보를 저장하면 서버가 저장해야 할 데이터가 많아지므로 → 사용자에게 그러한 데이터를 가지고 있도록 하기위해, 전달해주는 것이다

전체모두 암호화되는 것이 아니라 1/3만이 암호화되는 것이기 때문에
→ 토큰을 탈취당하면 유저정보가 그대로 노출될 수있기 때문에
→ 내용부분에 유저의 이름, 핸드폰번호, 주소, 실제 아이디값을 저장하는 것이 아니라 pk값으로 저장한다

토큰의 구조 (1) : 헤더

토큰의 타입과 해시알고리즘의 정보가 들어있다
BASE64의 방식으로 암호화가 아닌 인코딩해서 JWT의 가장 첫 부분에 기록된다

인코딩만 해도 사람이 알아볼 수 없긴 하다..!

{"alg":"HS256","typ":"JWT"}

토큰의 구조 (2) : 내용 payload

user-id는 단순한 pk값으로 1이라고 되어있다
: 유저의 이름, 핸드폰번호, 주소, 실제아이디값이 저장되면 보안이 어렵기 때문에 pk값으로 저장된다
만료시간 exp을 나타내는 공개 클레임
클라이언트와 서버간 협의하에 사용하는 비공개 클레임
위의 공개클레임 및 비공개클레임을 조합하여 작성한 뒤 → BASE64 방식을 인코딩하여 두번째 요소로 위치한다

{"user-id" : 1, "exp" : 14595452131 }

토큰의 구조 (3) : 서명 signature

JWT가 원본 그대로라는 것을 확인할 때 사용하는 부분이다
BASE64URL, 인코드된 header, payload, JWT secret(별도생성) → 헤더에 저장된 지정 암호 알고리즘으로 암호화하여 전송한다 복호화 가능하다
프론트엔드가 JWT를 백엔드 API서버로 전송하면 → 서버에서는 전송받은 JWT의 서명부분을 복호화하여 → 서버에 생성한 JWT가 맞는지 확인한다
header와 payload는 암호화가 아닌 BASE64 인코딩한 것이기 때문에 → 누구나 원본을 볼 수 있어서 개인정보를 담으면 안된다

계약서의 위변조를 막기위해 서로 사인하는 것이라 생각하자!

profile
새로운 것을 도전하고 노력한다
post-custom-banner

0개의 댓글