티스토리 뷰

카테고리 없음

JWT(JsonWebToken)

CodingDreamTree 2023. 10. 23. 05:14

JWT를 사용자 정보 인증을 하는 수단으로  얕게 알고 있었으나 구체적으로 파악해보려 한다.

 

JWT에 대한 공식 RFC문서는 RFC 8725 - JSON Web Token Best Current Practices (ietf.org) 이며 7519로부터

업데이트 되었다.

 

정의는 다음과 같다.

JSON 웹 토큰은 서명 또는 암호화 할 수 있는 일련의 클레임 이 포함된 JSON 보안 토큰이다. 디지털 신원 영역, 

애플리케이션 영역 모두에서 수많은 프로토콜, 애플리케이션에서 간단한  보안 토큰 형식으로 사용되고 있다.

 

1. 용어

 

JWT Claims Set

JWT 가 전달하는 클레임이 포함된 JSON 객체

 

Claim

주제에 대한 정보를 주장하거나 나타내는 것으로 페이로드(Payload)부분의 요소로 사용된다. 
이름(Claim Name)/값(Claim Value) 쌍으로 표시된다.

 

Nested JWT

하나의 JWT안에서 다른 JWT를 포함하는 개념 상위JWT에서 하위 JWT에 권한관리나 별도 보안 처리를 할 수 있다.

 

Unsecured JWT

무결성이 보호되지 않거나 암호화 되지 않은 JWT

 

Collision-Resistant Name

JWT의 Claim 이름을 선택할때 중요한 원칙 중 하나를 나타내며 서로 충돌하지 않도록 명명해야하는 것을 의미한다.

클레임 이름은 고유해야 하며 일관성이 있어야하고 보안에 취약하지 않아야 합니다.

JWT 표준 클레임 이름을 사용하는 것을 권장하는것을 의미한다.

 

StringOrURI

특정 클레임의 데이터 타입을 나타내며, 값으로 문자열(대소문자구분)을 사용할 수 있지만 ":" 를 포함하는 모든 값은 URI이여야 한다.

 

JOSE( Json Object Siging and Encryption )

JWS, JWE의 설정 및 메타데이터 정보를 포함하며 알고리즘, 키, 토큰 유형 및 기타 관련정보를 나타내

헤더이며 JSON 객체 이다.

EX)

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

alg(Algorithm): JWS, JWE를 생성하거나 검증하는 데 사용되는 알고리즘을 지정한다. HS256은 HMAC SHA-256을 사용하는 알고리즘을

나타낸다.

typ(Type): 토큰의 유형을 지정한다. JWE나 JWS 의 경우 JWT로 설정된다.

이 헤더 정보는 Base64로 인코딩 된다.

 

JWS(Json Web Signature)

JWT의 일부 구성요소 중 하나로 데이터의 무결성과 인증을 위한 데이터 포맷이다.

주로 서명과 인증(로그인 정보)을 처리할 때 사용된다.

JWS는 JOSE(Json Object Siging and Encryption)헤더와 서명된 페이로드로 구성된다. 

 

JWE(Json Web Encryption)

JWT의 구성요소로 데이터를 암호화하고 안전하게 전송하기 위한 데이터 포맷이다. 

주로 민감한 데이터를 보호하기 위해 사용된다. JOSE 헤더와 암호화된 페이로드로 구성된다.

 

 

2. JWT 구성요소 

 

1) Header

위에서  설명한 JOSE 헤더가 다음과 같은 객체를 가지고 있다면

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

UTF-8 인코딩 문자를 Base64url 로 인코딩 하면 다음과 같은 값이 나온다.

eyJ0eXAiOiJKV1QiLA0KICJhbGciOiJIUzI1NiJ9

 

Header에는 3종류의 Header Parameter가 존재한다.

Registerd Header Parameter Names

 

Json 웹 서명 및 암호화 헤더 매개변수로서 레지스트리에 등록되어있다.

공식(표준)스펙이라고 보면 쉽다.

alg(Algorithm) - 사용할 암호화 알고리즘을 정의한다.

enc(Encryption Algorithm) - 콘텐츠를 암호화할 알고리즘을 정의한다.

zip(Compression Algorithm) - 암호화하기전 텍스트에 적용되는 압축 알고리즘을 정의한다.

typ(Type) - 토큰의 유형을 정의한다. ("JWT")

 

그외에도 많은 내용이 설명되어있으니 

이 두 문서를 확인하여보자.

RFC 7515: JSON Web Signature (JWS) (rfc-editor.org)

RFC 7516 - JSON Web Encryption (JWE) (ietf.org)

 

 

  Public Header Parameter Names

사용자가 임의로 정의한 Header Parameter를 말한다. 중복된 이름으로 되어 충돌되지않게 설정해야한다.

공개적으로 사용되지만 JWT사용자 간 협의에 따라 정의된다. 

 

  Private Header Parameter Names

생산자와 소비자간의 헤더 매개변수이다. 생산자 임의로 매개변수이름과 값을 사용할 수 있다.

 

 

2) Payload

다음은 JWT 클레임 세트에 대한 예시이다.

{
  "iss":"joe",
  "exp":1300819380,
  "http://example.com/is_root":true
}

해당 클레임 세트는 UTF-8의 octet sequence에 의해 다음과 같은 배열로 변환되며

[123, 34, 105, 115, 115, 34, 58, 34, 106, 111, 101, 34, 44, 13, 10,
   32, 34, 101, 120, 112, 34, 58, 49, 51, 48, 48, 56, 49, 57, 51, 56,
   48, 44, 13, 10, 32, 34, 104, 116, 116, 112, 58, 47, 47, 101, 120, 97,
   109, 112, 108, 101, 46, 99, 111, 109, 47, 105, 115, 95, 114, 111,
   111, 116, 34, 58, 116, 114, 117, 101, 125]

이를 다시 Base64url로 인코딩 하면 JWS 페이로드 부분은 다음과 같이 된다.

eyJpc3MiOiJqb2UiLA0KICJleHAiOjEzMDA4MTkzODAsDQogImh0dHA6Ly9leGFtcGxlLmNvbS9pc19yb290Ijp0cnVlfQ

 

Claim에는 3가지 종류가 있다.

 

Registerd Claim Names

 

JWT에서 (공식)표준적으로 사용하는 Claim이며 필수는 아니지만 권장 Claim으로써 사용된다.

일반적으로 iss(Issuer), sub(Subject), aud(Audience)가 포함되는데 여러가지를 다 보자면

iss(Issuer) - 토큰을 발급한 주체를 나타낸다.

sub(Subject) - JWT가 나타내는 주제(문맥)를 말한다. 

aud(Audience) - 토큰을 받을 수신자를 나타낸다.

exp(Expiration Time) - JWT의 만료시간을 의미하며 그 이후로는 해당 토큰을 이용하게 해서는 안된다.

nbf(not before) - JWT가 처리되기 이전의 시간을 의미하며 해당 시간 이전에 사용이 불가능해야한다.

iat(Issued At) - JWT가 발행된 시간

jti(JWT ID) - JWT에 대한 고유 식별자 (로그 아웃시 무효화 시키거나, 중복 처리를 방지하는데 사용)

 

Public Claim Names

사용자가 임의로 정의한 Claim을 말한다. 중복된 이름으로 되어 충돌되지않게 설정해야한다.

공개적으로 사용되지만 JWT사용자 간 협의에 따라 정의된다. 

JSON Web Token (JWT) (iana.org) 이곳에 저장된 규칙대로 사용하는 것을 권장한다.

 

Private Claim Names

사용자나 애플리케이션에 의한 사용자 지정 클레임 이름을 가리킨다.

통신간 정해진 규칙대로 클레임이름을 지정하여 사용하면 된다.

 

 

 

 

3) Signature

 

서명과 관련된 부분을 만들려면 인코딩된 헤더, 인코딩된 페이로드, 비밀키, 헤더에 지정된 알고리즘을 가져와

서명해야한다.

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

 

 

위 세가지를 종합하면 다음과 예시와 같은 JWT가 만들어지게 된다.

 

출처:  JSON Web Token Introduction - jwt.io

 

 

 

3. JWT의 취약점

1. JWT 변조

JWT가 서명되지 않았거나 암호화되지 않은 경우, JWT를 변조 할 수 있다. (데이터 무결설 보장 X)

 

2. 비밀키(서명된 키) 노출

서명, 암호화에 사용되는 키가 노출 되면 공격자가 서명 생성 혹은 JWT해독할 수 있다.

 

3. JWT 페이로드 정보 노출

JWT 페이로드에는 클라이언트와 관련된 정보가 포함될 수 있어, 민감한 데이터는 노출되지 않도록 한다.

 

4. JWT 탈취

JWT가 안전하게 보호되지 않은 경우 제 3자가 JWT를 탈취하여 사용자 계정에 엑세스 하거나 도용할 수 있다.

 

5. 유효 기간 설정

유효기간을 지나치게 오래 설정하는 경우, 악의적인 사용자가 만료전 JWT를 오랜기간 사용가능하다. 

 

 

그외 궁금한 것들 정리

1) JWT를 base64url로 인코딩 하여 보내는 이유?

 

1. URL 안정성

URL에 안전하지 않은 문자를 생성할 수 있다.

'+' , '/' 와 같은 문자가 그런것들 인데, base64url의 경우 '+' 를 '-'로, '/'를 '_'로 대체하여 URL에 안전하게 만든다.

2. 구분기호 . 사용

JWT에서 헤더, 페이로드, 시그니처 구분을 위해 '.' 를 사용하는데 일반적인Json구조의 경우 마침표가

어느곳에나 있을 수 있다. (base64url은 마침표가 포함 될 수 없다는 보장이 있다.)

출처: base64 - What is the reason for encoding JWT? - Stack Overflow

 

2) Bearer Token이란?

 

Bearer token은 화폐와 같다. 단지 Token을 소지하고 있으면 사용할 수 있다는 의미이다.

해당 토큰을 어떻게 얻었는지와 같이 수단에 대해서는 중요하지 않고 소지하다는 것만을 중요하게 판단하여

검증하고 처리한다.

 

Http Request Header Authorization에 Bearer를 쓰는 것은 Bearer 방식의 인증 토큰을 사용한다는 것을 의미한다.

Bearer토큰은 OAuth 2.0, JWT와 함께 사용되며 주로 자원 서버로부터 접근 권한을 얻을 때 사용된다.

출처: What are Bearer Tokens? - YouTube

 

 

3) Access Token, Refresh Token

 

● Access Token

 

클라이언트 애플리케이션이 API 서버 또는 리소스 서버에 접근할 때 사용하는 인증 토큰

권한부여, 사용자 식별에 사용된다

대부분 짧은 유효기간(30분 ~ 1시간)을 가지고 있다.

 

Refresh Token

 

Access Token을 재발급 하고 갱신하는데 사용되는 토큰이다.

Access Token보다 상대적으로 보안이 중요하여 안전한 저장소에 저장해야하고

긴 유효기간(15 ~ 30일 이상)을 가지고 있다.

 

공지사항
최근에 올라온 글
최근에 달린 댓글
Total
Today
Yesterday
링크
«   2024/11   »
1 2
3 4 5 6 7 8 9
10 11 12 13 14 15 16
17 18 19 20 21 22 23
24 25 26 27 28 29 30
글 보관함