[CS] JWT가 신뢰성을 가지는 이유 및 개념

Onam Kwon·2023년 2월 1일
3

CS

목록 보기
18/22
post-thumbnail
post-custom-banner

JWT

  • 미리 알고 있어야 할 내용인 인증 및 인가 개념 클릭!!
  • JWT란 JSON Web Token의 약자로 서버가 클라이언트에게 인증되었다는 의미로 토큰을 발급할때 사용하는 방식이며, 해외에서는 좆 토큰 이라고 부르기도 한다.
    • 이 토큰은 유일하며 토큰을 발급받은 클라이언트는 매번 서버에 요청을 보낼 때 마다 요청의 헤더에 토큰을 담아 함께 요청한다.
    • 토큰과 함께 온 요청을 서버는 해당 서버에서 제공한 토큰과 일치 여부를 확인 후 해당 요청이 정상적인 요청인지 확인한다.
  • 크게 세가지 파트로 나눌수 있으며 그 구성은 아래와 같다.
    • Header(헤더)
    • Payload(페이로드)
    • Signature(시그니처, 서명)

Header

{
  "alg": "HS256",
  "typ": "JWT"
}
  • 토큰을 암호화 할때 사용한 알고리즘과 토큰의 타입이 담겨있다.

Payload

{
  "sub": "ThisIsATitle",
  "name": "Five",
  "iat": 1516239022
}
  • 서버에서 첨부한 사용자 권한 정보, 데이터 및 토큰의 발생 시간과 만료 시간 등이 명시되어 있다.
    • payload 자체는 암호화 되어있지 않기 때문에 비밀번호와 같은 민감한 정보를 넣으면 안되고 유저를 구분할 수 있는 유니크한 값을 정도를 넣어야 한다.

Signature

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload), "YourSecretKeyValue"
)
  • JWT에서 핵심이며 토큰의 위변조 여부를 확인하는데 사용한다.
  • Signature는 header, payload를 Base64URLEncode를 적용하고 개인 키로 서명한 뒤, 마지막으로 header의 alg에서 명시한 알고리즘을 적용한다.
    • 아래와 같은 모습
Signature = HS256(Base64URLEncode(header)+"."+Base64URLEncode(payload), "YourSecretKeyValue")
  • headerpayload는 인코딩된 값이기 때문에 제3자가 복호화 하거나 조작하기 굉장히 쉽지만 signature는 서버에서 비밀키를 이용해 관리하기 때문에 비밀키만 유출되지 않으면 복호화를 할수가 없다.

토큰 인증이 신뢰성을 가지는 이유

  • http 통신에 대해 배울때 GET통신은 보안이 약하니 보안이 필요한 요청에 대해서는 POST통신을 이용해 body를 사용해야 한다고 배웠는데 JWT토큰은 GET통신의 header를 이용한다. 암호화가 되어 있다고 해도jwt는 중간에 누군가에 의해 빼앗길 수도 있고 수정될 수 있다.
  • 또한 JWT는 Base64로 암호화를 하기 때문에 바로 복호화가 가능하다.
  • 그럼에도 불구하고 왜 jwt 토큰이 신뢰성을 가지는지에 대해 알아보겠다.

JWT의 목적은 signature(인증, 서명)

  • JWT의 목적은 토큰 안에 들어있는 정보가 아니라 해당 토큰이 신뢰 가능한 토큰인지 확인하는것이 목적이다.
  • JWT는 Base64로 암호화 하기 때문에 디버거를 사용해 인코딩된 JWT를 아주 쉽게 복호화가 가능하다.
  • 그래서 실제로 그런지 아래에 직접 실험해본 과정을 가져왔다.

  • https://jwt.io
  • 위의 사이트에서 JWT토큰을 직접 만들어 볼 수 있고 위 사진처럼 임의로 하나의 JWT 토큰을 만들었다.
    • header와 payload를 설정했으며 signature부분엔 MySecretCode라는 key를 사용했다.

  • https://www.base64decode.org
  • 위 사이트에 들어가 아까 만들어둔 JWT를 복사해 붙혀넣기 후 DECODE 버튼을 누르면 위 사진의 아래 처럼 header 와 payload는 손쉽게 알아낼 수 있었다.
  • 서버는 클라이언트로부터 JWT를 받으면 header, payload를 서버의 key값을 이용해 시그니처를 다시 만들고 이를 비교하여 일치했을 경우 통과시킨다.
  • JWT토큰은 이제 알다시피 A(header) + B(payload) + C(signature)로 구성되어 있다.
    • JWT => A + B + C
    • 만약 누군가 토큰의 내용이 담겨져 있는 payload를 수정했다면 B'로 표기하겠다.
      • 임의의 유저에 의해 수정된 JWT => A + B' + C
  • 서버가 유저로부터 A+B+C로 구성된 토큰을 받았을때 서버는 A+B로 C를 다시 만든 후 요청때 받은 토큰의 C와 서버가 만든 C를 비교후 일치한다면 통과시킨다.
    • 서버에 비밀키가 안전하게 보관되어 있으므로 위조가 되지 않았다면 두 서명은 일치하기 때문!
  • 만약 서버가 유저로부터 A+B'+C로 구성된 변조 토큰을 받았을때 서버는 A+B'로 C'를(변조된 서명) 만든다. 이후, 서버는 요청때 받은 토큰의 C와 서버가 만든 C'를 비교한다.
    • 이때 서버는 변조된 payload인 B'를 받았으므로 A+B'로 새로만든 서명은 C가 아닌 C'가 나올수밖에 없다.
      • B'로 서명을 새로 만들었기 때문!
    • 따라서 C와 C'는 다르므로 이때 받은 요청은 서버가 신뢰할수 없다고 판단한다.
  • 여러번 반복해서 적지만 토큰의 진짜 목적은 정보 보호가 아닌 위조 방지이며 이는 서명을 통해 이루어진다.
  • signature에 사용된 비밀키는 서버에서 안전하게 보관되며, 만약 JWT가 중간에 변조되어도 기존에 존재하던 signature과 같은 비밀키를 사용해 새롭게 signature를 만들어 비교하기 때문!!!!!
    • 아주 중요함.

JWT 장점

  • Header 와 Payload로 구성된 Signature와 비밀키를 이용하기 때문에 데이터의 수정을 방지.
  • Session과 다르게 인증 정보를 저장하는 저장소가 필요없다.
  • 토큰 자체에 토큰 검증에 필요한 자체적인 정보를 담고 있다(장점이자 단점).

JWT 단점

  • 토큰 자체적으로 길이가 길다.
  • payload는 탈취당할 위험이 있으므로 민감한 데이터를 넣지 않아야 한다.
  • 토큰 자체에 토큰 검증에 필요한 자체적인 정보를 담고 있다(장점이자 단점).
  • 토큰을 클라이언트에서 저장하기 때문에 토큰을 탈취당하면 서버에서 대처하기가 힘듦.
    • jwt 는 주된 목적인 위조 방지에 좋지만 토큰 자체를 빼앗겨 사용할 경우 대처가 힘들기 때문에 토큰을 클라이언트에 저장할 때 안전하게 보관해야 하며 토큰 자체의 사용 기한도 짧게 설정해야 한다.
profile
권오남 / Onam Kwon
post-custom-banner

0개의 댓글