본문 바로가기
cs

[정보보안] JSON Web Token(JWT) 설명

by 최연탄 2023. 3. 2.
728x90
반응형

참고: https://jwt.io/introduction

JSON Web Token(JWT) 이란?

JSON Web Token(JWT)은 당사자 사이의 정보를 JSON 객체로 안전하게 전송하기 위한 방법을 정의하는 개방형 표준(RFC 7519)입니다. 이 당사자 간 정보는 디지털 서명되어 있으므로 검증되었고 신뢰할 수 있습니다. JWT는 비밀번호(HMAC 알고리즘 사용) 또는 RSA, ECDSA를 사용한 공개/개인 키 쌍으로 서명할 수 있습니다.

JWT는 당사자 간 보안을 제공하기 위해 암호화할 수도 있지만, 이보다는 서명된 토큰에 더 초점이 맞춰져 있습니다. 서명된 토큰은 해당 토큰에 포함된 claim의 무결성을 증명하지만 암호화된 토큰은 다른 당사자에게 claim을 숨길 뿐 입니다. 토큰이 공용/개인 키 쌍을 사용하여 서명되었다면 이는 개인 키를 보유한 당사자만 인증할 수 있습니다.

JSON Web Token을 언제 사용하나?

다음은 JSON Web Token을 사용하기 적절한 시나리오입니다:

  • Authorization: 이는 JWT를 사용하는 가장 일반적인 시나리오입니다. 먼저 사용자가 로그인하면 이후의 각 요청에 JWT를 포함하여 전달합니다. 그러면 사용자는 해당 토큰으로 허용된 경로, 서비스, 리소스에 접근할 수 있습니다. Single Sign On(SSO)은 오버헤드가 적고 다양한 도메인에서 쉽게 사용할 수 있기 때문에 현재 JWT가 널리 사용되고 있습니다.
  • Information Exchange: JSON Web Token은 당사자 간 정보를 안전하게 전송하는 좋은 방법입니다. 공용/개인 키 쌍을 사용하여 JWT를 서명할 수 있으므로 보낸 사람이 누구인지 확인할 수 있습니다. 또한 헤더와 페이로드를 사용하여 서명을 생성하므로 콘텐츠가 변조되지 않았음을 확인할 수도 있습니다.

JSON Web Token의 구조는?

JWT는 점(.)으로 구분되는 세 가지 부분으로 구성되어 있습니다.

  • Header
  • Payload
  • Signature

이에 따라 일반적인 JWT는 다음과 같이 생겼습니다.

xxxxx.yyyyy.zzzzz

이제 각각의 부분을 자세히 알아보겠습니다.

Header

헤더는 일반적으로 JWT의 토큰 타입과 사용 중인 서명 알고리즘(예: HMAC SHA256 또는 RSA)의 두 부분으로 구성됩니다. 예를 들면:

{
  "alg": "HS256",
  "typ": "JWT"
}

그 다음 위의 JSON 객체를 JWT의 첫 번째 부분에 들어가도록 Base64 Url 인코딩을 합니다.

Payload

토큰의 두 번째 부분은 claim이 들어있는 페이로드입니다. claim은 엔티티(일반적으로 사용자) 및 추가 데이터에 관한 설명입니다. claim의 종류로는 registered, public, private 세 가지 유형이 있습니다.

  • Registered claims: 이는 필수는 아니지만 유용하게 쓸 수 있고 공용으로 사용하기 위해 권장하는 미리 정의된 claim 집합입니다. 예로는 iss, exp, sub, aud 등등 입니다. JWT는 가능한 컴팩트해야 하기 때문에 claim 이름은 3 글자로 이루어집니다.
  • Public claims: 이는 JWT 사용자에 의해 마음대로 정의될 수 있습니다. 하지만 충돌을 방지하기위해 IANA JSON Web Token Registry에서 정의한 충돌 방지 네임스페이스를 가지는 URI로 정의해야 합니다.
  • Private claims: 이는 사용하기로 동의한 당사자 간에 정보를 공유하기 위해 만든 사용자 정의 claim 입니다.

다음은 payload의 예제 입니다:

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

payload는 Base64 URL 인코딩되어 JSON Web Token의 두 번째 부분에 위치합니다.

주의할 점은 서명된 토큰의 경우 정보를 위변조로 부터 보호하는 반면 누구나 읽을 수 있습니다. JWT의 payload 또는 header에 암호화되지 않은 비밀 정보를 넣지 마십시오.

Signature

signature 부분을 만드려면 인코딩된 header, 인코딩된 payload, 암호, 헤더에서 지정한 알고리즘을 가져와서 서명해야합니다.

예를 들어 HMAC SHA256 알고리즘을 사용하려는 경우 서명은 다음과 같은 방법으로 생성됩니다:

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

signature는 메시지가 도중에 변경되지 않았는지 확인하는 데 사용되며, 개인 키로 서명된 토큰의 경우 JWT 발신자가 누구인지도 확인할 수도 있습니다.

모두 합치면

결과물은 HTML과 HTTP 환경에서 사용할 수 있도록 점으로 구분된 세 개의 Base64 URL 문자열이며, SAML과 같은 XML 기반 표준과 비교해 더욱 컴팩트합니다.

다음은 위에서 설명한 header와 payload가 인코딩된 JWT이고 암호로 서명되었습니다.

JTW를 이용하여 위의 개념을 실행해 보려면 jwt.io 디버거를 사용하여 JWT를 디코딩, 검증, 생성할 수 있습니다.

JSON Web Token은 어떻게 작동하는가?

authentication 시 사용자가 자격 증명을 사용하여 성공적으로 로그인하면 JSON Web Token이 리턴됩니다. 토큰은 자격 증명이기 때문에 보안 이슈가 생기지 않도록 세심한 주의를 기울여야 합니다. 대표적인 예로 토큰은 필요 이상으로 오래 보관해서는 안됩니다.

또한 부주의하게 민감한 세션 데이터를 브라우저 저장소(예: local storage)에 저장해서는 안됩니다.

사용자의 에이전트는 사용자가 보호된 경로 또는 리소스에 접근하길 원할 때 마다 JWT를 전송해야 합니다. 일반적으로 Bearer 스키마를 사용해 Authorization 헤더에 넣습니다. 헤더의 내용은 다음과 같아야합니다:

Authorization: Bearer <token>

이는 특정한 경우, stateless authorization 메커니즘일 수도 있습니다. 서버의 보호된 경로는 Authorization 헤더에 유효한 JWT가 있는지 확인하고, JWT가 있으면 사용자는 보호된 리소스에 액세스할 수 있습니다. JWT에 필요한 데이터가 포함된 경우 특정 작업에 대해 데이터베이스를 쿼리할 필요성이 줄어들 수 있습니다. 항상 그렇지는 않지만 말입니다.

HTTP 헤더를 통해 JWT 토큰을 전송할 경우 너무 커지지 않도록 해야 합니다. 일부 서버는 헤더 크기가 8KB 이상인 경우 허용하지 않습니다. 사용자의 권한을 모두 집어넣는 것과 같이 JWT 토큰에 너무 많은 정보를 넣으려는 경우 Auth0 Fine-Grained Authorization과 같은 대체 솔루션이 필요할 수도 있습니다.

서명된 토큰을 사용하면 토큰을 변경할 수 없더라도 토큰에 포함된 모든 정보가 사용자 또는 다른 사용자에게 노출됩니다. 이는 토큰 안에 비밀 정보를 넣지 말아야 한다는 것을 의미합니다.

왜 JSON Web Token을 사용해야 하는가?

JSON Web Tokens(JWT)을 Simple Web Tokens(SWT)과 Security Assertion Markup Language Tokens(SAML)과 비교했을 때의 이점에 대해 알아보겠습니다.

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

보안 측면에서 SWT는 HMAC 알고리즘을 사용하는 공유 암호에 의해서만 대칭적으로 서명할 수 있습니다. 그러나 JWT 및 SAML 토큰은 서명을 위해 X.509 인증서 형태의 공용/개인 키 쌍을 사용할 수 있습니다. 모호한 보안 허점을 없애기 위해 XML 디지털 서명으로 XML에 서명하는 것은 JSON 서명의 단순성에 비교하면 매우 어려운 것 입니다.

JSON 파서는 데이터를 객체에 직접 매핑할 수 있기 때문에 대부분의 프로그래밍 언어에서 널리 쓰이고 있습니다. 반대로 XML에는 기본 기능으로 문서 대 객체 매핑이 없습니다. 따라서 SAML assertions 보다 JWT로 작업하는게 더 쉽습니다.

사용법과 관련하여 JWT는 인터넷 규모로 사용됩니다. 이는 여러 플랫폼, 특히 모바일에서 JSON Web Token의 클라이언트 측 처리 용이성이 뛰어납니다.

관련 글

자바스크립트 base64 사용 방법

네트워크 CORS, 해결 방법

반응형

댓글