Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[SEMINAR 7] Security #8

Open
seoyeonjin opened this issue Dec 8, 2024 · 0 comments
Open

[SEMINAR 7] Security #8

seoyeonjin opened this issue Dec 8, 2024 · 0 comments

Comments

@seoyeonjin
Copy link
Collaborator

Q. JWT token 에 대해 리서치해보세요.

JWT란? (Json Web Token)

로그인을 구현하기 위한 방법으로는 세션방식, 쿠키 방식, 토큰 방식 등이 있다. 이중 토큰 방식은

  • 브라우저와 서버가 인증에 대한 정보를 가지고 있지 않은 상태(stateless)에서
  • 토큰에 포함된 정보를 사용하여 사용자를 식별하고 권한을 확인하는 방법이다.

jwt는 아래 사진과 같이 .으로 구분된 3가지 부분으로 구성되어있다.각 부분은 JSON 형태이며, Base64Url로 인코딩되어있다.

  • header: 알고리즘 및 토큰 종류 정보를 담고 있는 부분
  • payload: 발급 시간, 만료 시간, 사용자 정보 등을 담고 있는 부분
  • signature: 헤더, 페이로드가 변조 되었는지를 확인하는 역할
    • 시그니처 생성 방법
      • header, payload의 값을 base64url로 인코딩
      • 시크릿 키를 이용해 인코딩 한 값을 Header에 정의한 알고리즘으로 해싱
      • 해싱한 값을 base64url로 인코딩

https://supertokens.com/static/b0172cabbcd583dd4ed222bdb83fc51a/9af93/jwt-structure.png (사진 참고)

어떻게 유효성을 검증하는가?

서버에서는 토큰 정보만을 활용하여 유효성을 검증한다.

  • header 검증
    1. base64로 디코딩하여 json 객체로 변환한다.
    2. 알고리즘이 서버에 지정된 알고리즘과 일치하는지 확인한다.
  • payload 검증
    1. base64로 디코딩하여 json 객체로 변환한다.
    2. 변환된 json 객체엇 발급 시간, 만료 시간, 사용자 정보 등을 확인한다.
    3. 만료 시간을 비교하여 유효한 토큰인지 확인한다.
    4. 디코딩한 사용자 정보가 서버에 저장된 사용자 정보와 일치하는지 확인한다.
  • signature 검증
    1. 헤더에 정의된 알고리즘을 사용해서 서버의 와 header + payload를 기반으로 새로운 signature를 생성한다.
    2. 생성된 signature와 토큰의 signature를 비교하여 일치하는지 확인한다.

key (알고리즘별로 사용하는 key가 다름)

  • HMAC: 대칭키 기반 (하나의 시크릿 키 사용)
  • RSA: 비대칭키 기반 (개인키로 서명, 공개키로 검증)
  • ECDSA: 비대칭키 기반 (개인키로 서명, 공개키로 검증)

탈취에 취약한 방법

토큰을 탈취하여 해당 사용자인 척 요청을 해도, 서버의 입장에서는 이를 무시할 수 없다. 한번의 탈취를 통해 영원히 다른 사용자인 척 요청을 할 수 있다면 보안적으로 큰 문제이다.

이점을 보완하기 위해 토큰의 만료 시간을 짧게 하여 토큰을 재발급 받아야하도록 했다. 하지만, 로그인 유지 시간이 짧아 로그인을 자주 해야 한다면 서비스를 사용하기 매우 불편할 것이다.

액세스 토큰과 리프레시 토큰

위에 언급한 문제를 보완하기 위해 리프레시 토큰을 사용할 수 있다.

일반적으로 사용하는 토큰은 액세스 토큰과 리프레시 토큰으로 나눌 수 있는데,

  • 액세스 토큰은 인증, 인가를 위해 사용하는 토큰이고
  • 리프레시 토큰은 액세스 토큰이 만료될 경우 액세스 토큰을 재발급받기 위해 사용하는 토큰이다.

액세스 토큰은 보안을 만료 시간을 짧게 설정하고, 리프레시 토큰은 액세스 토큰보다 긴 기간으로 만료 시간을 설정한다. 리프레시 토큰을 탈취 당하면 보안이 위험해지기 때문에 클라이언트에 저장하기보다는 서버에 보관하거나, HTTP-Only 쿠키에 저장하는 방식으로 관리한다.

재발급 방법

  • 클라 → 서버로 요청을 보냈을 때 액세스 토큰이 만료되었다면 클라이언트에게 알린다.
  • 클라 → 서버로 리프레시 토큰을 보내 새로운 액세스 토큰을 요청한다.
  • 서버는 새로운 액세스 토큰을 발급해 클라이언트로 보낸다.
  • 클라 → 서버로 새로운 액세스 토큰으로 요청을 다시 보낸다.
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

1 participant