[TIL #27] - 인증 인가 && Session VS Token / Bcrypt/ JWT

Sean yang~~·2022년 9월 7일
0
post-thumbnail
post-custom-banner

인증(Authentication)

인증이란?

  • 어떤 개체의 신원을 확인하는 과정이다.
  • 보통 어떤 인증요소를 증거로 자신을 증명한다.
  • 온라인에서는 ID와 패스워드를 입력하는 행위가 인증이 될 수 있다
  • 실생황에서는 공공기관에서 신원확인 시 신분증을 보여주는 것을 생각해보면 된다.
  • 여러 개의 정차가 있을 수 있다.
    • 은행의 경우, 본인인증 후 OTP, 보안카드 등의 절차를 추가로 거친다.

인가(Authorization)

  • 어떤 리소스에 접근할 수 있는지, 어떤 동작을 수행할 수 있는지 검즘한다.
  • 접근 권한을 얻는 일이다.
  • 현실에서는 비행기 여권과 함께 가져가는 비행기 티켓을 예로 들 수 있다.
    • 여권으로 신분확인이 되더라고 비행기 티켓이 있어야 비행기에 탈 수 있다.
  • 인터넷 기반 앱에서는 보톤 토큰이라 부르는 것을 사용한다.
  • 유저는 자신의 인가 세부사항을 가진 토큰을 통해 서버에 인증받는다.
  • 서버는 유저의 토큰을 보고 권한이 있는지 판단한다.

인증 VS 인가

사실 인증과 인가는 한번에 쓰일 수도 있다. 회사에 출근하면 찍는 지문 인식기는 내가 누구인지도 인식하면서, 내가 회사 출입문을 통과할 수 있도록 회사 내부 접근을 인가하기도 한다.

인증은 인가로 이어질 수 있지만, 인가는 인증으로 이어지지 않을 수도 있다. 편의점에서 구매한 버스카드는 내가 누구인지에 대한 인증 정보는 담고 잇지 안지만, 잔액이 충분하다면 얼마든지 버스 탑승을 인가받을 수 있다.

[ Authentication ] Session VS Token Based Authentication

바로 직전의 통신도 기억 못하는 HTTP

HTTP는 stateless 한 특성을 가지기 때문에 각 통신의 상태는 저장되지 않습니다. 하지만 우리가 웹 서비스를 사용할 떄를 생각해봅시다. 매번 새 페이지를 요청할 때마다 로그인을 해야 한다면 사용이 불가능할 것입니다.

기억하는 척 하기 위해 사용되는 세션과 토큰

이 문제를 해결하기 위한 대표적인 도구 두 가지가 바로 세션(Session) 과 토큰(Token) 입니다.

유저가 로그인을 시도할 때 서버상에서 일치하는 유저 정보를 찾았다면 인증(Authentication) 확인의 표시로 세션이나 토큰을 발급/전달 해 줍니다.

그럼 웹 브라우저 측에서 해당 세션/토큰 정보를 받아 간직하고 있다가 새로운 request를 보낼때마다 인가(Authorization)를 위해 해당 세션/토큰을 함께 보냅니다.

그런데 세션과 토큰 모두 존재 목적은 거의 같지만 차이점은 존재합니다. 그 중 가장 큰 차이점은 세션은 데이터베이스 서버에 저장된다는 것, 토큰은 클라이언트 측에서만 저장한다는 점입니다.

쿠키(Cookie)

웹을 이용하다보면 흔히 쿠키라는 이름을 듣는다. 쿠키는 클라이언트 측에서 로컬 웹 브라우저가 저장하는 데이터다. 인증을 하는 과정에서 처음에 서버는 쿠키를 생성해서 클라이언트에게 보내게 된다면, 클라이언트는 쿠키를 웹 브라우저에 key-value 형식으로 저장이 된다. 이후 클라이언트가 데이터를 요청시 헤더에 쿠키를 실어서 서버에 보내게된다. 따라서 로그인 정보가 쿠키에 담겨져있다면 더이상의 인증은 필요없게 된다.

쿠키의 유효기간은 서버에서 설정하여 보낼 수 있다. 유효기간이 지나면 쿠키는 자동으로 소멸된다. 만약 유효기간을 설정하지 않는다면 웹 브라우저를 종료하는 순간 사라진다.

그런데 사실 인증을 여러번 하지 않는 큰 이유중 하나가 보안에 취약하다는 점이다. 서버에게 인증 요청을 하기 위해서 네크워크로 개인정보를 보내는데 이를 탈취해 나갈 가능성이 있기때문에 보완점이 필요했다. 구리는 이를 보완하고자 세션(Session)을 사용한다.

쿠키 특징

  1. 이름, 값, 만료일(저장 기간 설정), 경로 정보로 구성되어 있다.
  2. 클라이언트에 총 300개의 쿠키를 저장할 수 있다.
  3. 하나의 도메인 당 20개의 쿠키를 가질 수 있다.
  4. 하나의 쿠키는 4KB(=4096byte)까지 저장 가능하다.

쿠키의 동작 순서

  1. 클라이언트가 페이지를 요청한다. (사용자가 웹사이트 접근)
  2. 웹 서버는 쿠키를 생성한다.
  3. 생성한 쿠키에 정보를 담아 HTTP 화면을 돌려줄 때, 같이 클라이언트에게 돌려준다.
  4. 넘겨 받은 쿠키는 클라이언트가 가지고 있다가(로컬 PC에 저장) 다시 서버에 요청할 대 요청과 함께 쿠키를 전송한다.
  5. 동일 사이트 재방문시 클라이언트의 PC에 해당 쿠키가 있는 경우, 요쳥 페이지와 함께 쿠키를 전송한다.

사용 예시

  1. 방문했던 사이트에 다시 방문 하였을 때 아이디와 비밀번호 자동 입력
  2. 팝업창을 통해 “오늘 이 창을 다시 보지 않기" 체크

세션(Session)

일정 시간동안 같은 사용자(브라우저)로 부터 들어오는 일련의 요구를 하나의 산태로 보고, 그 상태를 일정하게 유지시키는 기술이다. 여기서 일정 시간은 방문자가 웹 브라우저를 통해 웹 서버에 접속한 시점으로부터 웹 브라우저를 종료하여 연결을 끝내는 시점을 말한다.

즉, 방문자가 웹 서버에 접속해 있는 상태를 하나의 단위로 보고 그것을 세션이라고 한다.

세션 특징

  1. 웹 서버의 웹 컨테이너의 상태를 유지하기 위한 정보를 저장한다.
  2. 웹 서버의 저장되는 쿠키(=세션 쿠키)
  3. 브라우저를 닫거나, 서버에서 세션을 삭제했을때만 삭제가 되므로, 쿠키보다 비교적 보안이 좋다.
  4. 저장 데이터에 제한이 없다. (서버 용량이 허용하는 한…)
  5. 각 클라이언트 고유 Session ID 를 부여한다. Session ID로 클라이언트를 구분하여 각 클라이언트 요구에 맞는 서비스 제공

세션의 동작 순서

  1. 클라이언트가 페이지를 요청한다. (사용자가 웹사이트 접근)
  2. 서버는 접근한 클라이언트의 Request-Header 필드인 Cookie를 확인하여, 클라이언트가 해당 session-id를 보냈는지 확인한다.
  3. seseion-id 가 존재하지 않는다면, 서버는 session-id를 생성해 클라이언트에게 돌려준다.
  4. 서버에서 클라이언트로 돌려준 session-id를 쿠키를 사용해 서버에 저장한다.
  5. 클라이언트 재접속 시, 이 쿠키(JSESSIONID)를 이용하여 session-id 값을 서버에 전달

사용 예시

화면이 이동해도 로그인이 풀리지 않고 로그아웃하기 전까지 유지

암호화의 종류

아직 나에게는 어려운 것 투성이였지만,, 그래도 정리를 해보려고한다. 머리에 넣자..

평문(Plaintext)

  • 해독 가능한 형태의 메세지
    암호문(Ciphertext)
  • 해독 불가능한 형태의 메세지
    암호화(Encryption)
  • 평문을 암호문으로 변환하는 과정
    복호화(Decryption)
  • 암호문을 편문으로 변환하는 과정

단방향 암호화(One-way cryptography)

단방향암호는 흔히 Hash를 이용해 암호화를 하는것으로, 임의의 평문을 hash 처리하였을때 그 복호화가 불가능한 암호화를 말한다. hash 처리된 암호문을 평문으로 복호화가 불가능하므로, 단방향 암호라고 부르며 패스워드 등에 사용된다.

ex)
웹사이트에 비밀버노를 입력하면, 해당 비밀번호의 hash 값만 서버에서 저장해서 서로 비교대조 후 사용자에게 access 권한을 부여한다. 즉, 데이터의 진위여부는 확인하고싶으나, 본데이터의 privacy를 지키고 싶은 경우에 사용한다.

  • 해시 알고리즘은 동일한 평문에 대해서 항상 동일 해시값을 갖습니다. 따라서 특정 해시 알고리즘에 대해서 어떠한 평문이 어떠한 해시값을 갖는지 알 수가 있습니다. 이런 특징을 이용하여 해시 함수의 해시 값들을 대량으로 정이한 테이블이 존대하며, 이를 레인보루 테이블이라고 한다.

  • 해시 함수는 본래 데이터를 빠르게 검색하기 위해서 탄생 되었습니다. 이러한 해시 함수의 빠른 처리 속도는 공격자에게 오리혀 장점이 됩니다.

솔팅(Salting) & 키 스트레칭(key stretching)

솔팅은 단방향 해시 함수를 통해 암ㅁ호화를 진행 할 때 본래 데이터에 추가적으로 랜덤한 데이터를 더하여 암호화를 진행하는 방식입니다. 원래 데이터에 추가 데이터가 포함되었기 때문에 원래 데이터의 해시값과 다르게 됩니다.

키 스트레칭은, 단방향 해시값을 계산 한후, 그 해시값을 또 다시 해시하고 또 이를 반복하는 방식입니다.

양방향 암호화 - 대칭키

대칭키 암호화란?

단방향 암호화와 달리 양방향 암호화는 암호화된 값을 다시 암호화 하기 전의 값으로 복호화가 가능합니다. 양방향 암호화는 암호화 알고리즘 키(key)을 이용해서 암호화를 진행하는데, 이 키를 통해서 암호화된 값을 보호할 수 있습니다.

  • 하지만, 대칭키 방식은 하나의 키를 이용하므로 다른 사람과 대칭키 기반으로 암호화 통신을 할 경우 상대방도 사전에 같은 키를 갖고 있어야 합니다. 이때, 키를 주고 받는 과정에거 키가 중간에 유출될 우려ㅏ 있고, 이로 인해 암호화 통신을 해킹당할 수 있습니다. 특이 여러 상대방과 통신할 경우 각각의 키를 관리하는 것은 더욱 어려워 진다는 단점이 있습니다.

양방향 암호화 - 비대칭키

비대칭키 암호화란?

비대칭키 암호화 또한 암호화와 복호화 모두 가능하며, 암호화를 진행 할 떄 키를 이용합니다. 비대칭키 암호화에서는 암호화 때 사용하는 키와 복호화 할 떄 사용하는 키를 다르게 사용한다. 일반적으로 다른 사람들에게 공개하는 Public key와 정대 노출을 하지 않는 private key가 있으며, 이 두개의 키를 key pair라고 부릅니다. 비대칭키 암호화는 암호화하는 키와 복호화 하는 키를 구분하여 대칭키 암호화의 고질적인 문제였던 키의 탈취 또는 관리의 단점 부븐을 보완할 수 있씁니다.

Bcrypt

Bcypt는 브루스 슈나이어타 설계한 키(key) 방식의 대칭형 블록 암호에 기반을 둔 암호화 해시 함수로써 Niels Provos 와 David Mazières가 설계했습니다. Bcrypt는 레인보우 테이블 공격을 방지하기 위해 솔팅과 키 스트레칭을 적용한 대표적인 예입니다.

  • 2b: 해시 알고리즘 식별자
  • 12: Cost Factor로 Key Stretching의 수 (2의 12승번)
  • 76taFAFPE9ydE0ZsuWkIZe : 16Byte 크기의 Salt, Base64로 인코딩된 22개의 문자
  • xWVjLBbTTHWc509/OLI5nM9d5r3fkRG : 24Byte의 해시 값, Base64로 인코딩된 31개의 문자

검증

Bcrypt는 단방향 해시 알고리즘 입니다. 따라서 복호화가 불가능 합니다. Berypt의 검증은 암호화된 값이 가지고 있는 알고리즘, Cost Factor, Salt를 이용합니다. 비교하고 싶은 평문을 암호화된 값이 가지고 있는 알고리즘, Cost Factor, Salt을 이용하여 해시를 진행한 후 암호화된 값과의 비교를 통해 검증을 진행 합니다.

JWT(JSON Web Token)

JWT는 클라이언트(사용자)dhk 서버간에 정보를 JSON 개체로 안전하게 전송하기 위한 개방형 표준(RFC 7519)입니다. SAML(Security Assertion Markup Langauge Token)보다 크기가 작아 더 컴팩트하게 사용할 수 있습니다.

JWT는 일반적으로 Base64로 인코딩된 데이터와 전자 서명으로 구성되어 있습니다. JWT 역시 데이터를 암호화 할 수 있지만, JWT가 전자 서명이 되어 있다는 점이 중요하다. 전자 서명된 JWT의 목적은 데이터를 숨기는 것이 아니라 데이터릐 신회성을 보장하는 것입니다. 그렇기 때문에 서명된 JWT와 함께 HTTPS를 사용하는 것이 좃습니다.

JWT을 이용한 인증 과정은 사용자 측에 사용자의 정보를 관리하는 토큰 기반 인증 메커니즘입니다. 따라서 서버에서 세션 정보를 저장하기 위해 세션 스토리지 또는 데이터베이스에 완전히 의존할 필요가 없습니다. 또한, 서버의 확장성과 멀티 기기 및 도메인에서의 활용에서도 이점을 가지고 잇습니다.

JWT의 구조

JWT는 3가지 구성요소(Header, Payload, Signature)로 이루어져 있으며, 각 구성 요소들은 dot(.)으로 구분이 되어 있습니다.

Header는 JWT의 첫번쨰 구성 요소이고, 일반적으로 2가지 정보를 담고 있습니다.

  • alg : Signature을 만드는데 사용한 알고리즘 정보
  • typ : Token의 타입

Payload

Payload는 JWT의 두번쨰 구성요소로 실질적으로 전달해야 하는 정보들을 가지고 있다. payload에 담긴 정보 하나하나를 claim 이라고 하는데, 3가지 종류의 claim이 존재합니다.

  • Regidtered claims: 이미 JWT 표준으로 지정된 claim입니다. 총 7가지의 registered claim이 존재하며, 해당 claim을 무조건 전부 사용해야 되는 것이 아니고 적절히 상황에 맞제 사용하면 됩니다.

  • lss : 토큰 발급자

  • sub : 토큰 제목

  • aud : 토큰 대상자

  • exp : 토큰 만료시간

  • iat : 토큰 발급 시간

  • nbf : 토큰 활성화 시간

  • jti : JWT의 고유 식별자

  • Public Claims: JWT를 사용하는 사람들이 공개적으로 정의할 수 있습니다. 그러나 기본에 이미 등록되어 있는 Claims와 충졸을 방지하려면 IANA JASON Web Token 레지스트를 참고하거나 UUID, OID, 도메인 이름 들을 사용해야 합니다.

  • Private Claims: Public Claims과 달리 오직 사용자와 서버 사이에서만 합의하여 사용하는 claim 입니다.

Signature

Signature는 JWT의 세번째 구성요소이고, 문자 그대로 JWT으 ㅣ서명 부분입니다. Header의 인코딩된 내용과 Payload의 인코딩된 내용을 더한 뒤에 Secret key와 알고리즘을 이용하여 암호된 값을 나타냅니다.

전달 ㅂ다은 토큰의 Header와 Payload를 서버의 secreat key를 이용해서 암호화를 진행합니다. 그리고 해당 값이 전달 받은 signature와 같은지 비교하여 JWT의 신뢰성을 확인 할 수 있습니다. 서버에서 관리하고 있는 Secret Key가 아닌 다른 Key로 JWT를 잘급 한다면 Signature가 달라지기 때문에 해당 JWT는 신뢰 할 수 없는 토큰입니다.

profile
나는 프론트엔드 개발자다!
post-custom-banner

0개의 댓글