인증 & 인가란?

Jetom·2021년 9월 29일
0

etc(언어 외의 기술)

목록 보기
6/11
post-thumbnail

프론트라면 알아야할 (물론 백엔드도.. 🙄) 인증 & 인가! 어휴 어렵지만 정리하면서 다시 개념을 차근차근 머리에 넣어보겠다..

인증?

어느 사이트의 회원가입을 하려면 필수로 거치는 핸드폰 문자 인증!(or 주민등록번호) 이 인증은 왜 하는걸까? 답은 간단하다! 우리 서비스를 누가 어떻게 쓰는지 확인하기 위함이다.

비밀번호

인증에는 가장 중요한 것은 바로 비밀번호이다! 중요한 이유는 바로 개인정보보호법에 의거하기 때문이다. 그렇다면 우리는 어떻게 관리해 주어야 할까? 바로 DB(= data base)에 해싱하여 복원할 수 없게 관리해 주어야한다. 그렇다면 해싱이라는것은 또 무엇인지 간략하게 알아보겠다!

해싱(hashing)

해싱이란 쉽게 말해 난독화 한다는 뜻인데, 우리가 패스워드를 '1234'라고 적어도 DB에는 '1234'가 온전히 들어가는것이 아닌 'E7qsk4asdf' 이런식의 알아 볼 수 없는 문자로 들어가기 때문에 DB에서도 온전한 비밀번호를 알지못한다. 그래서 우리가 패스워드를 잊어버린다면 재설정 하라는것이 그 이유이다! 그렇다면 해싱을 어떻게 하는것일까? 해쉬는 단방향과 양방향이 있는데 단방향부터 살펴보겠다.

  • 단방향 해쉬

단방향 해쉬는 인풋과 아웃풋을 1:1로 매칭하는 결괏값을 나타내는데, 이 같은 허점을 이용해 가능한 경우의 수를 저장시켜 놓은 표를 rainbow table이라고 부르며 아래의 그림과 같이 해시값을 유추해서 판매하는 서비스도 존재한다.

👇 rainbow table 간단 예시(https://ko.wikipedia.org/wiki/%EB%A0%88%EC%9D%B8%EB%B3%B4_%ED%85%8C%EC%9D%B4%EB%B8%94)

  • 양방향 해쉬

단방향의 취약점을 보완하기 위해 나온것이 SALTING & Key Stretching이다. 이 방법은 salt + 패스워드를 합친 방법인데 이때 salt는 랜덤으로 생성한 문자열이며, 이 값들을 해시값으로 저장한다. 이 때, 해커가 해시값을 쉽게 알지못하게 salting 및 해싱을 여러번 반복하는 것이 Key Stretching이라고 한다.

예를들어 내 패스워드는 '1234'이지만 이 숫자에 salt 문자열인 'jetom'을 합쳐서 최종적으로는 'Q9awk30qozk'라는 값이 나오지만 이것을 더 알아 볼 수 없게 Key Stretching하여 'O1kizqE9makal'이란 값을 나오게한다는 것이다.

bcrypt

SALTING & Key Stretching을 우리가 하기엔 많~이 힘들기(?)때문에 이 작업을 편리하게 만들어주는 대표적인 라이브러리이다. bcrypt는 salt값 & 해시값 & 반복횟수를 같이보관해 DB설계를 복잡하게 할 필요가 없게 만들어주는 고마운 라이브러리이다!


인가?

인증은 많이 들어봤는데, 인가란 단어는 다소 생소하다고 느껴지는데 쉽게 말해서 사용자가 서버에 로그인하면 사용자가 맞는지 확인하는 과정이라고 생각하자. http는 stateless한 성질을 가지고있어서 다른 페이지로 넘어갈때마다 인증을 요구하겠지만 서버에서 토큰(token)을 준다면 이 토큰으로 사용자 정보와 권한을 확인한다!

JSON Web Token(JWT)

선택적 서명 및 선택적 암호화를 사용하여 데이터를 만들기 위한 인터넷 표준으로, 페이로드는 몇몇 클레임(claim) 표명(assert)을 처리하는 JSON을 보관하고 있다. 토큰은 비공개 시크릿 키 또는 공개/비공개 키를 사용하여 서명된다.

https://ko.wikipedia.org/wiki/JSON_%EC%9B%B9_%ED%86%A0%ED%81%B0

위의 설명에서 선택적 서명 및 선택적 암호화를 사용하여 데이터를 만들기 위한 인터넷 표준이라고 나와있는데, 쉽게 말해 JSON 객체를 사용해 입장권을 발급해준다고 생각하면된다. (JSON에 대해 모르신다면 매우 유감.. 🙄)

그렇다면 어떤 형식으로 어떻게 들어가는지 살펴보자!

  • header
    헤더는 토큰의 타입과 해시알고리즘 정보가 들어가며 BASE64라는 방식으로 인코딩하여 JWT의 가장 첫 부분에 기록된다.
{ 
  "alg": "HS256",
  "typ": "JWT"
}

💡 Base64란 Binary Data를 Text로 바꾸는 Encoding(binary-to-text encoding schemes)의 하나로써 Binary Data를 Character set에 영향을 받지 않는 공통 ASCII 영역의 문자로만 이루어진 문자열로 바꾸는 Encoding이다.

https://effectivesquid.tistory.com/entry/Base64-%EC%9D%B8%EC%BD%94%EB%94%A9%EC%9D%B4%EB%9E%80

  • payload
    payload는 exp와 같이 만료시간을 나타내는 공개 클레임과 협의하에 사용하는 비공개 클레임이 있다. 이 두가지 요소를 조합하여 작성한뒤 헤더와 같은 BASE64 방식으로 인코딩하여 두 번째 요소로 위치한다.
{
  "user-id": 1,
  "name": "Jetom Kim",
  "exp": 1539517391
}
  • signature

시그니쳐는 인코딩된 header와 payload 그리고 JWT secret을 헤더에 지정된 암호 알고리즘으로 암호화하여 전송한다. (이때 개인정보를 담아서는 안된다)

👇 jwt.io로 만들어본 JWT

profile
사람이 좋은 인간 리트리버 신혜리입니다🐶

0개의 댓글