JWT(JSON Web Token)

TwentyFiveSeven·2021년 4월 12일
1
post-thumbnail

1. JWT란 ?

  • JWT란 JSON Web Token의 약자로 당사자간에 정보를 JSON 개체로 안전하게 전송하기위한 Compact하고 독립적인 방식을 정의하는 open standard (RFC 7519)입니다.
  • 추상적인 설명보다는 JWT의 구조부터 설명해보겠습니다.

2. JWT 구조

JWT는 Header, Payload, Signature로 이뤄져있고, (Header Encode Url).(Payload Encode Url).(Signature Encode Url) 형식으로 '.'을 기준으로 구분됩니다.

Header에는 두가지 정보를 가지고 있습니다.

{
  "alg": "HS256",
  "typ": "JWT"
}
  • alg : Signature에 사용될 알고리즘 정의 (HMAC SHA256 or RSA)
  • typ : Token의 타입을 정의

그런 다음이 JSON은 Base64Url로 인코딩되어 JWT의 첫 번째 부분을 형성합니다.

Payload

Payload는 토큰에 담을 정보가 들어있고, 이는 3가지의 클레임 종류로 구분됩니다.

{
    "iss": "velopert.com",   //Registered claims
    "exp": "1485270000000",  //Registered claims
    "https://velopert.com/jwt_claims/is_admin": true,   //Public claims
    "userId": "11028373727102",  //Private claims
    "username": "velopert"   //Private claims
}
  • Registered claims: 등록된 클레임들은 서비스에서 필요한 정보들이 아닌, 토큰에 대한 정보들을 담기위하여 이름이 이미 정해진 클레임들입니다. 등록된 클레임의 사용은 모두 선택적입니다.
    • 이에 포함되는 클레임은 다음과 같습니다.
    • iss: 토큰 발급자 (issuer)
    • sub: 토큰 제목 (subject)
    • aud: 토큰 대상자 (audience)
    • exp: 토큰의 만료시간 (expiraton), 시간은 NumericDate 형식으로 되어있어야 하며 (예: 1480849147370) 언제나 현재 시간보다 이후로 설정되어있어야합니다.
    • nbf: Not Before 를 의미하며, 토큰의 활성 날짜와 비슷한 개념입니다. 여기에도 NumericDate 형식으로 날짜를 지정하며, 이 날짜가 지나기 전까지는 토큰이 처리되지 않습니다.
    • iat: 토큰이 발급된 시간 (issued at), 이 값을 사용하여 토큰의 age 가 얼마나 되었는지 판단 할 수 있습니다.
    • jti: JWT의 고유 식별자로서, 주로 중복적인 처리를 방지하기 위하여 사용됩니다. 일회용 토큰에 사용하면 유용합니다.
  • Public claims: 공개 클레임들은 충돌이 방지된 (collision-resistant) 이름을 가지고 있어야 합니다. 충돌을 방지하기 위해서는, 클레임 이름을 URI 형식으로 짓습니다.
  • Private claims: 등록된 클레임도아니고, 공개된 클레임들도 아닙니다. 양 측간에 (보통 클라이언트 <->서버) 협의하에 사용되는 클레임 이름들입니다. 공개 클레임과는 달리 이름이 중복되어 충돌이 될 수 있으니 사용할때에 유의해야합니다.

그런 다음이 JSON은 Base64Url로 인코딩되어 JWT의 두 번째 부분을 형성합니다.
인코딩 후에 생성되는 '=' 패딩문자는 url-safe하지 않으므로 제거해줘야합니다.

Signature

Signature는 메시지가 변경되지 않았음을 확인하는 데(무결성 확인) 사용되며 개인 키로 서명 된 토큰의 경우 JWT의 발신자가 자신이 말하는 사람인지 확인할 수도 있습니다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)
  • Base64로 인코딩한 Header, Payload 값과 Secret값을 통해 HMAC Algorithm으로 구한 해쉬값을 다시 Base64로 인코딩합니다.



3. JWT Verify

앞서 설명한 구조로 생성된 JWT는 어떻게 Verify할까?? RFC7519 문서를 참고해서 간략히 설명해보겠습니다.

  1. JWT에 마침표 ( '.')가 하나 이상 포함되어 있는지 확인합니다.
  2. Header 디코딩및 문법 확인합니다.
  3. JWT가 JWS인지 JWE인지 확인합니다.
    • JWS란
      • Header.Payload.Signature 구조를 가지는 우리가 흔히알고 있는 JWT이다.
    • JWE란
      • JWS는 Claims에 대한 정보를 암호화 하지 않기 때문에 사용자 정보가 누출될 수 있다. 이를 개선하기 위해 데이터를 암호화하는 것이 JWE다.
    • JWS, JWE를 구분하는 방법은 JWE RFC7516에서 확인하였습니다.
        1. JWS는 3개로 분류되고, JWE는 5개로 분류 되기 때문에 각각 '.'문자가 2개, 4개 존재합니다.
        1. Header의 arg 파라미터 값이 JWS는 RSA, SHA256 등이 존재하지만 JWE는 Key Encryption, Key Wrapping, Direct Key Agreement를 나타냅니다.
  4. JWS, JWE 각각의 맞게 디코딩 과정을 진행합니다. (JWS는 Payload를 디코딩)
  5. Signature와 일치하는지 확인합니다.

4. JWT의 장점

SWT (Simple Web Tokens) 및 SAML (Security Assertion Markup Language Tokens)과 비교할 때 JSON 웹 토큰 (JWT)의 이점에 대해 이야기 해 보겠습니다.

  1. JSON은 XML보다 장황하지 않기 때문에 인코딩 될 때 크기도 작아 져 JWT가 SAML보다 더 간결합니다. 따라서 JWT는 HTML 및 HTTP 환경에서 전달하기에 좋은 선택입니다.

  2. 보안 측면에서 SWT는 HMAC 알고리즘을 사용하는 공유 비밀에 의해서만 대칭 적으로 서명 될 수 있습니다. 그러나 JWT 및 SAML 토큰은 서명을 위해 X.509 인증서 형식의 공개 / 개인 키 쌍을 사용할 수 있습니다.

  3. 모호한 보안 허점을 도입하지 않고 XML 디지털 서명으로 XML에 서명하는 것은 JSON 서명의 단순성과 비교할 때 매우 어렵습니다.

  4. JSON 파서는 객체에 직접 매핑되기 때문에 대부분의 프로그래밍 언어에서 일반적입니다. 반대로 XML에는 자연스러운 문서 대 개체 매핑이 없습니다. 따라서 SAML 어설 션보다 JWT로 작업하기가 더 쉽습니다.

  5. 사용과 관련하여 JWT는 인터넷 규모로 사용됩니다. 이는 여러 플랫폼, 특히 모바일에서 JSON 웹 토큰의 클라이언트 측 처리 용이성을 강조합니다.

마치며

JWT는 흔하게 접근할 수 있고 많이 사용되는 것이기 때문에 명확히 JWT를 학습하고 넘어가면 좋을 것 같다는 생각을 하여 이렇게 정리를 하게되었습니다. 내용이 많이 생략된 부분이 있기 때문에 JWT Documentation에서 꼭 확인하시면서 RFC문서들도 함께 확인해보시면 좋을 것 같습니다 !

참고
https://jwt.io/introduction
https://tools.ietf.org/html/rfc7519
https://tools.ietf.org/html/rfc7515
https://tools.ietf.org/html/rfc7516
https://medium.facilelogin.com/jwt-jws-and-jwe-for-not-so-dummies-b63310d201a3

profile
부지런한 웹개발자🌙

0개의 댓글