JWT

bearMin·2024년 8월 12일

들어가면서

지난 블로그 Cookie, Session, Token 에서 Token에 대해서 소개를 할 때 JWT에 대해서 간략하게 설명을 한 적이 있다. 하지만 이 JWT는 설명할 내용이 너무나도 많기 때문에 이번에 JWT에 대해서 조금 더 자세하게 알아보고자 한다!


JWT란?

정의는?

정보를 비밀리에 전달하거나 인증할 때 주로 사용하는 토큰으로 JSON 객체를 이용함

JWT는 Json Web Token의 약자로 웹표준(RFC 7519)으로서 JSON 객체를 사용하여 가볍고 자가수용적인 방식으로 정보를 안정성 있게 전달해준다.

즉, JWT는 일반적으로 클라이언트와 서버 사이에서 통신할 때 권한을 위해 사용을 하는 Token이다.


구조는?

JWT는 . 을 구분자로 3가지의 문자열로 되어있다. Header, Payload, Signature 세 파트로 나눠져 있으며 각각이 의미하는 것은 다음과 같다.

Header

  • JWT의 정보
  • 토큰 타입과 사용된 서명 알고리즘을 지정
{
    "alg": "HS256",
    "typ": "JWT"
}

여기서 typ 은 Token의 Type을 지정하는 것이며, JWT를 사용한다면 JWT라고 작성을 해주면 된다.

alg 은 암호화 알고리즘을 뜻한다. 주로 HS256, RS256 가 쓰인다.

💡 HS256, RS256이란?
우선 동일하게 있는 S256이란 SHA256 알고리즘을 뜻한다. SHA256 알고리즘은 데이터 무결성을 위해 
사용되는 암호화 해쉬 알고리즘이다. 256비트로 구성되며 64자리 문자열을 반환한다. 

HS256 = HMAC + SHA256
: 대칭키 암호화 알고리즘과 SHA256 알고리즘을 같이 사용하는 것이다.

RS256 = RSA + SHA256
: 비대칭키 암호화 알고리즘과 SHA256 알고리즘을 같이 사용하는 것이다.

대칭키와 비대칭키 암호화 방식에 대해서 궁금하다면 여기로!


Payload

  • JWT의 내용

  • Token에 담을 정보가 있음

  • 정보를 담는 한 조각을 Claim이라고 함

    💡 Claim이란?
    key-value의 한 쌍으로 이루어진 정보를 담는 공간
    하나의 Token에는 여러 개의 Claim이 들어갈 수 있다!
  • 노출과 수정이 가능하기 때문에인증이 필요한 최소한의 정보만을 담는 것이 좋음

Claim의 종류에도 여러가지가 있다!


Registered Claims

Payload 부분에 들어갈 특별한 정보들이다. 이미 JWT 표준에 정의가 되어있는 것들이며, 일반적으로 널리 사용되는 정보들을 나타낸다.

{
    "iss": "Token 발급자",
    "sub": "Token 제목",
    "aud": "Token 대상자",
    "exp": "Token 만료시간, NumbericDate 형식(ex.1480849147370)",
    "nbf": "해당 시간이 지나야 Token이 활성화, NumbericDate 형식",
    "iat": "Token 발급시간",
    "jti": "JWT 고유 식별자, 주로 중복적인 처리 방지에 사용"
}

위는 Registered Claim의 종류들이며, 모두 선택사항이다.


Public Claims

Payload에 들어가는 정보 중 누구나 사용할 수 있는 정보를 뜻한다. JWT 표준에 따라 정의가 되진 않았지만 필요에 따라 사용자가 임의로 추가할 수 있는 부분이다.

{
    "https://profile.com/jwt_claims": true
}

만약 사용자의 프로필 사진 URL을 보내고 싶다면 위에처럼 URL을 작성하면 된다.

이 정보들은 보낸 사람과 받은 사람 사이에서 사용이 될 수 있다. 다만 표준에 따라 정의하는 것이 아니기 때문에 중복이 되지 않도록 유의해야하며, 추가적인 정보들만 넣어야한다. 보안과 관련된 민감한 사항을 작성할 경우 쉽게 정보에 노출될 수 있다..!


Private Claims

Payload에 들어가는 정보 중 특정한 사람들에게만 공유되어야 하는 비공개 정보를 뜻한다. JWT 표준에 따라 정의되지 않은 사용자 정의 정보이며, 민감한 정보를 포함할 때 유용하다.

{
    "adminID": "개발자용",
    "role": "admin"
}

위처럼 사용자의 ID나 권한 정보와 같은 민감한 정보들을 포함한다. 이런 민감한 정보의 경우 보안 조치를 취해서 안전한 전송과 저장을 보장할 수 있도록 해야한다!


Signature

  • 가장 중요한 부분
  • Header의 인코딩 값과 Payload의 인코딩 값을 합친 후 서버가 지정한 Secret Key로 암호화를 시켜 생성 ⇒ Token을 변조하기 어렵게 함
    • 만일 Payload의 정보가 조작이 됐을 경우 Signature 부분은 기존 Payload의 정보를 가지고 암호화를 시켰기 때문에 이 Payload가 다른 결과값이 나오기 때문에 조작의 여부 판단이 가능!!
HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  "secret"
)

이처럼 Header 부분과 Payload 부분을 인코딩하고 합친 것을 서버의 secret key로 암호화 작업을 진행한다!

웃픈 이야기…!
JWT를 사용할 때 secret key는 어렵고 길게 작성을 해서 보안을 강화시켜야한다.
그러나 JWT 강의에서 secret key를 간단하게 “secret” 이라고 작성을 했었고, 이를 그대로 사용한 여러 회사들이 해커들에 의해 보안이 뚫린 적이 있다..!

그외에도 해커들을 우습게 보고? 혹은 JWT가 너무 완벽하다고 생각해서? Secret Key를 너무 간단하게 작성한 경우 보안이 뚫릴 수 있으니 Secret Key는 무조건 길고 연상할 수 없는 임의의 난수로 지정을 해야한다!!

추가로 이러한 구조에 대해서 쉽게 알아볼 수 있는 사이트가 있다!

jwt.io

Header와 Payload, Signature를 작성해서 JWT로 인코딩도 해보고 다른 블로그에서 인코딩된 JWT를 디코딩을 통해 데이터를 확인해볼수도 있다!


특징은?

JWT의 특징은 기존의 Session 기반 인증과 비교하여 설명할 수 있다!

Session 기반 인증이란 사용자의 인증 정보가 서버의 Session 저장소에 저장이 되는 방식으로

  1. 사용자가 로그인을 할 경우
  2. 인증 정보를 서버의 Session 저장소에 저장하고 사용자에게는 저장된 Session 저장소의 식별자인 Session ID를 발급한다.
  3. 이 Session ID는 Cookie에 저장이 되며
  4. 요청마다 Session ID를 통해 서버에서 Session 저장소를 직접 확인하여 응답을 하게 된다.

그에 반해 Token 기반 인증이란 인증 정보를 클라이언트가 직접 들고 있는 방식으로

  1. 사용자가 로그인을 할 경우
  2. 서버에서는 Token을 만들어 클라이언트에게 전송을 하고
  3. 이후 클라이언트는 요청시 해당 Token을 함께 전송한다.
  4. 서버는 해당 Token이 유효한지 확인하여 알맞은 응답을 하게 된다.

이때 Session 방식에서는 서버가 직접 인증의 작업을 진행하기 때문에 서버를 확장하게 될 경우 한개의 Session 저장소가 아닌 각 서버마다 동일한 Session 저장소가 필요하게 되며, 여러 별도의 작업이 필요하다. 이는 확장성에 매우 불편하다. 또한, Session 저장소의 공간이 필요하기 때문에 서버에 부담이 된다..

그러나 Token 인증 방식에서는 클라이언트가 저장을 하고 Token의 유효성만 검증을 하면 되기 때문에 높은 확장성을 가진다. 그리고 별도의 저장공간이 필요없다.


이러한 특징 때문에 Session 인증 방식 대신에 Token 인증 방식을 사용을 하는 경우가 있다. 그리고 이 Token 인증 방식에서 사용되는 Token이 바로 JWT인 것이다.

이 JWT의 장점에 대해서 조금 더 살펴보자!

장점

  • C, Java, Python, JavaScript 등 대부분의 주로 사용이 되는 프로그래밍 언어에서 지원이 된다.
  • Header와 Payload를 가지고 Signature를 생성하기 때문에 데이터의 위변조를 방지할 수 있다.
  • 인증 정보에 대한 별도의 저장소가 필요없어 서버의 부하가 낮아진다.
  • Token에 대한 기본 정보와 전달할 정보, Token이 검증되었다는 Signature 등 필요한 정보를 자체적으로 가지고 있다.
  • Token은 한번 발급이 됐을 경우 유효기간이 만료될 때까지 사용이 가능하다.

그렇다면 단점은 없을까?

단점

  • Token의 길이가 길어 인증 요청이 많아질수록 네트워크 부하가 심해진다.
  • Payload 자체는 암호화가 되지 않는다. ⇒ 민감한 정보나 보안상 중요한 정보들을 담아서는 안된다.
  • 탈취당하면 대처하기 어렵다.

요청할 때 어떻게 하지?

JWT는 클라이언트가 저장을 하고 서버에 요청을 보낼 때 같이 보내준다고 하는데, 그럼 어떻게 같이 보내주는 것일까?

일반적으로 요청 메세지는 HTTP Method, Header, Body 이렇게 3 부분으로 이루어져 있다.

Body에는 요청을 보낼 때 필요한 데이터들을 넣을 수 있다.
여기서 우리가 중요하게 봐야할 것은 바로 Header이다!


HTTP 통신에서는 보호된 서버 리소스를 접근하는 클라이언트의 인증 정보를 확인하는 HTTP 인증 프레임워크가 있다.

Authorization: <type> <credentials>

위처럼 인증 Header에 요청을 사용하며 올바른 인증 정보를 넣으면 요청한 데이터를 받을 수 있다.

주로 사용을 하는 방식은 OAuth 2.0 프레임워크에서 사용하는 Token 인증 방식Bearer 인증 방식이다!

💡 OAuth 2.0?
인증을 위한 개방형 표준 프로토콜이며, 구글, 카카오, 네이버 등에서 제공하는 
소셜 로그인 기능도 이 프로토콜을 기반으로 한 사용자 인증 기능을 제공한다.

Bearer소유자라는 뜻으로 해당 토큰의 소유자에게 권한을 부여해줘라는 의미로 이름을 붙였다고 한다!

Authorization: Bearer <token>

만일 토큰이 “aase.ewtat.3awe” 이라고 한다면, “Bearer aase.ewtat.3awe” 라고 작성을 해주면 된다!


뭘 사용하지?

주로 Java로 개발을 하기 때문에 Spring에서 JWT를 구현할 때 어떻게 해야할지에 관해서 얘기를 안할 수 없을 것 같다.

어떻게 구현하긴, 한줄한줄 구현하면 되지! 라고 생각할 수 있지만 그러기엔 이미 충분히 잘 나와있는 라이브러리들이 많다..!! 따라서 Java에는 어떤 라이브러리들이 있는지 살펴보고 해당 라이브러리를 사용하는 방법에 대해서 간단하게 설명을 해보겠다!


JJWT?

JJWTJava JWT라는 뜻으로 Java에서 JWT를 생성, 서명, 검증 및 디코딩하기 위한 라이브러리이다.

이 라이브러리가 제공하는 기능을 살펴보자!

  • JWT 생성
    : JWT Token을 생성하고 필요한 Claim을 추가할 수 있음
  • JWT Signature
    : JWT를 비밀 키 또는 공개 키를 사용하여 Signature를 진행할 수 있음
  • JWT 검증
    : JWT의 Signature와 만료 시간을 검증할 수 있음
  • JWT 디코딩
    : JWT의 Payload를 디코딩하여 포함된 데이터를 추출할 수 있음

다른 JWT 라이브러리는?

JJWT 이외에 Java에서 사용하는 다른 JWT 라이브러리는 없을까? 물론! 다양하게 존재한다!

  • nimbus-jose-jwt
    : 보안과 관련된 다양한 기능을 제공하는 라이브러리로 JWE, JWS, JWT 모두를 지원
  • auth0/java-jwt
    : Auth0에서 제공하는 라이브러리로, 다양한 JWT 기능을 지원
  • vertx-jwt
    : Vert.x 프로젝트의 일부로, 고성능 비동기 애플리케이션에 적합

JJWT를 사용하는 이유는?

다른 JWT 라이브러리도 많은데 Spring에서 JWT를 구현하려고 할 때 많이 사용하는 라이브러리는 JJWT이다. 왜 JJWT를 사용하는 것일까?

  • 간편한 사용
    : 직관적인 API로 인해 사용이 쉽다.
  • 기능성
    : Claim 설정, Signature, 검증 등의 기능을 간단하게 구현할 수 있다.
  • 문서화
    : 잘 정리된 문서와 예제를 제공한다. 특히, jjwt에 매우 친절한 README와 잘 형성된 커뮤니티가 있다!
  • 경량
    : 라이브러리가 경량이고, 대부분의 경우에 필요한 모든 기능을 포함하고 있다. 특히, 가장 많은 암호화 알고리즘과 편의 메소드를 제공하는 것으로 확인된다.

이처럼 현재 Java에서는 JJWT가 가장 좋은 선택지로 여겨진다. 물론 이것은 취향의 차이이기 때문에 충분히 다른 라이브러리를 사용할 수 있다!


Spring Security?

Spring Security는 인증과 권한 관리, 데이터 보호 기능을 포함하여 웹 개발에서 필수적인 사용자 관리 기능을 구현하는데 도움을 주는 Spring 프레임워크이다.


Spring Security를 사용하는 이유는?

Spring Security는 라이브러리가 아닌데 왜 나왔는지 궁금한 사람들이 있을 것이다. 물론 Spring Security 없이도 JWT 기반 인증을 구현할 수 있다.

그렇다면 많은 사람들이 Spring Security를 사용 이유는 무엇일까?

  • 인증 및 권한 부여
    : 인증과 권한 부여를 간편하게 처리할 수 있도록 한다.
  • 보안 필터 체인
    : 다양한 보안 필터(예: 인증 필터, 권한 부여 필터)를 체인 형태로 제공하여, 요청이 애플리케이션에 도달하기 전에 여러 보안 검사를 수행한다.
  • 통합
    : Spring 프레임워크와 밀접하게 통합되어 있어, Spring 기반 애플리케이션에서 손쉽게 사용할 수 있다.
  • 확장성
    : 사용자 정의 보안 로직을 쉽게 구현하고 확장할 수 있는 구조를 제공한다.
  • 비밀번호 인코딩
    : 안전한 비밀번호 저장을 위해 다양한 비밀번호 인코딩 메커니즘을 제공한다.

물론 Spring Security를 꼭 사용해야하는 것은 아니다. 다음과 같은 보안 프레임워크들 역시 존재한다.

  • Apache Shiro
    : 인증, 권한 부여, 암호화 및 세션 관리 기능을 제공하는 보안 프레임워크
  • Keycloak
    : SSO 및 IDM(Identity and Access Management)을 제공하는 오픈소스 솔루션

그래서?

이렇게 대안이 있음에도 불구하고 Spring Security를 사용하는 이유는 Spring 기반 애플리케이션에서 매우 유용하며 통합된 보안 솔루션을 제공하여 많은 보안 관련 작업을 간소화할 수 있기 때문이다. 또한 많은 시간을 절약할 수 있다는 장점 역시 있다!


JWT의 보안 고려사항은?

JWT는 매우 안전한 방식이 아니다. 여러 방식으로 문제가 생길 수 있고 이를 방지하기 위해서 고려해야할 부분들이 분명 존재한다. 하나씩 살펴보자!


Secret Key 관리?

JWT는 서버의 Secret Key를 사용해서 Signuatrue를 진행한다. 따라서 이 Secret Key의 관리는 매우 중요하다!

Secret Key 보안을 위해서는 다음과 같은 방식을 사용할 수 있다!

  • Secret Key의 보호
    : 서명을 위한 비밀 키는 절대로 유출되면 안된다. 따라서 이를 보호하기 위해 키를 환경 변수에 저장하거나, 키 관리 서비스(KMS)를 사용한다.
    💡 KMS란?
    Key Management Service의 약자로 애플리케이션의 중요한 데이터를 안전하게 보호하기 위해, 
    암호화 키를 간편하게 생성하고 안전하게 저장/관리하는 서비스
    
    AWS KMS, Azure Key Valut 등 클라우드 서비스에서 제공
  • 키 회전(Key Rotation)
    : 주기적으로 비밀 키를 교체하여 보안을 강화할 수 있다. 키가 교체될 때마다 새로운 키로 서명하고 기존 키로 검증할 수 있도록 해야 한다.

Token 만료 시간 설정?

Token이 탈취된다면 이를 막을 수 있는 방법이 거의 없다. 따라서 Token의 탈취된 경우를 방지하기 위해서 Token의 만료 시간을 짧게 설정하는 방법이 있다. 그렇게 된다면 Token이 탈취되어도 얼마 지나지 않아 무용지물이 되도록 만들 수 있기 때문이다.

이 만료 시간을 설정할 때 생각해야할 부분은 다음과 같다!

  • 만료 시간 설정
    : JWT는 만료 시간(exp) Claim을 사용하여 토큰의 유효 기간을 지정
  • Refresh Token
    : 짧은 만료 시간을 설정했을 때 사용자가 계속 액세스할 수 있도록 Refresh Token을 사용하여 새로운 Access Token을 발급하는 방식을 사용

Token 저장 위치?

발급한 Token을 어디에 저장할 것인지에 따라서 생각해야할 부분이 각각 다르다!

  • HTTP Only Cookie
    : 브라우저에서 접근할 수 없는 HTTP Only Cookie에 저장하면 XSS 공격에 대한 방어를 강화할 수 있다.
    💡 XSS 공격이란?
    웹 사이트 관리자가 아닌 다른 사람이 웹 페이지에 악성 스크립트를 삽입하는 공격 방식
  • Local Storage
    : Local Storage에 저장할 경우 XSS 공격에 취약할 수 있으므로, 반드시 XSS 방지 코드를 적용해야 한다.
  • Secure Cookie
    : HTTPS 연결에서만 전송되도록 Secure 플래그를 설정한다.

Token 무효화 전략?

위에서 Token이 탈취되었을 때를 방지하기 위한 방법으로 만료 시간을 짧게 설정하는 방식이 있다고 했다. 하지만 결국 탈취가 되었을 때 만료가 되기 전까지는 사용할 수 있다는 말이 된다. 따라서 이 Token 자체를 무효화하기 위한 전략도 생각을 해볼 필요가 있다!

  • 로그아웃 처리
    : JWT는 기본적으로 상태 비저장(stateless)하기 때문에 로그아웃 시 Token을 무효화하는 방법이 필요하다.
  • 블랙리스트
    : 서버에 블랙리스트를 유지하여 로그아웃된 토큰이나 유효하지 않은 토큰을 차단할 수 있다. 다만 이 방식은 stateless 라는 특징을 해치는 방식이기 때문에 잘 고려해보고 선택을 해야한다.

CSRF 공격 방지?

Cross Site Request Forgery의 약자로 인증된 사용자가 웹 애플리케이션에 특정 요청을 보내도록 유도하는 공격행위를 뜻한다. 즉, 사이트 공격자의 요청이 사용자의 요청인 것처럼 속이는 공격 방식이다.

이 CSRF의 공격을 막기 위해서는 다음과 같은 방식을 생각할 수 있다!

  • SameSite Cookie
    : JWT를 Cookie에 저장하는 경우, SameSite 속성을 설정하여 CSRF 공격을 방지할 수 있다.
  • CSRF Token
    : 폼 제출 시 CSRF Token을 함께 전송하여 요청의 유효성을 검증한다.

Signature 및 암호화?

JWT에서 가장 중요한 부분이라고 설명했던 Signature 부분 역시 보안상 매우 중요하다!

  • Signature 알고리즘
    : 강력한 Signature 알고리즘(예: HS256, RS256)을 사용하여 Token의 무결성을 보장한다.
  • Signature 검증
    : 서버에서 수신한 JWT의 Signature를 반드시 검증하여 변조되지 않았는지 확인한다.

또한 Signature 말고도 Payload에 민감한 정보를 사용하기 위해서 암호화를 진행해야 하는 경우가 있을 것이다. 이때 다음과 같은 방식도 생각해볼 수 있다!

  • JWE 사용
    : 민감한 정보를 JWT에 포함할 경우 JWE(JSON Web Encryption)를 사용하여 Payload를 암호화한다.
    → JWE가 무엇인지는 조금 뒤에 자세하게 알아보자!
  • 암호화 알고리즘
    : 강력한 암호화 알고리즘(AES, RSA)을 사용하여 Token의 기밀성을 보장한다.

Claim의 최소화?

JWT의 Payload는 암호화가 되지 않기 때문에 이 Claim에는 민감한 정보를 포함시키지 않는 것이 좋다고 했다. 따라서 Claim에는 최소한의 정보만을 포함하는 것을 고려해봐야한다!

  • 불필요한 정보 배제
    : JWT Payload에는 최소한의 필요한 정보만 포함시킨다.
    ex) 사용자 ID, 역할, 만료 시간 등

적절한 Claim 검증?

Signature로 검증을 하지만 Claim에 있는 정보들로 한번 더 확인을 하는 작업이 있다면 조금 더 보안에 신경을 써줄 수 있다!

  • 발급자(iss) 검증
    : JWT의 발급자를 검증하여 신뢰할 수 있는 발급자가 서명했는지 확인한다.
  • 청중(aud) 검증
    : JWT의 청중을 검증하여 Token이 의도한 수신자에게 발급되었는지 확인한다.
  • 발급 시간(iat) 검증
    : 발급 시간 Claim을 검증하여 Token이 적절한 시간에 발급되었는지 확인한다.

HTTPS 사용?

단순 HTTP 전송을 하면 보안상 허점이 생길 수 있다. 때문에 HTTP에 Secure를 더한 HTTPS 전송을 사용하는 방법도 있다!

  • HTTPS 전송
    : 모든 JWT는 HTTPS를 통해 전송하여 전송 중에 도청이나 변조가 발생하지 않도록 한다. 이를 통해 Man-in-the-Middle (MITM) 공격을 방지할 수 있다.
    💡 MITM이란?
    공격자가 비밀리에 도청을 하거나 이동하는 정보를 수정하기 위해서 두 당사자 사이에서 통신을 가로채는 공격 방식

Token 재사용 방지?

Token의 탈취를 방지하기 위한 다른 방법이라고 생각할 수 있다. Token을 재사용하는 것을 막아 탈취 당하더라도 문제가 생기지 않도록 할 수 있다!

  • 1회용 Token
    : 일부 상황에서는 JWT를 1회용으로 만들어서 재사용을 방지한다.
    ex) 중요한 작업을 수행할 때마다 새로운 JWT를 발급받아 사용

그래서?

이렇게 총 10개 정도의 보안 고려사항들에 대해서 알아보았다. 이러한 보안 고려사항을 철저히 준수하면 JWT를 사용하는 애플리케이션의 보안을 강화할 수 있다! 또한, 각 사항들은 서로 상호보완적이기 때문에 여러 가지 방법을 함께 사용하여 조금 더 심도 깊은 보안 전략을 구축하는 것이 좋다!


JWT 관련 기술은?

위의 보안 고려사항에서도 잠시 나왔지만 JWT에는 그와 관련된 기술들이 존재한다. 기술들이 무엇이 있는지 각각 어떤 역할을 하는지에 대해서 하나씩 살펴보자!


JWS란?

JWS는 JSON Web Signature의 약자로 데이터를 보호하기 위해 디지털 서명을 사용하여 JWT를 생성하는 방법을 정의한다. JWS를 사용하면 클라이언트와 서버 간에 전달될 때 Claim이 변조되지 않았는지 확인할 수 있다.

즉, 데이터의 무결성을 보장하기 위해 사용한다!

JWT와 뭐가 달라? 라고 할 수도 있다.

간단하게 얘기를 하자면 JWT는 JSON 형식의 Token 전체를 의미하지만 JWS는 JWT의 Signature 부분에 해당한다. JWS는 JWT의 서명된 형태인 것이다!

JWS는 데이터의 무결성을 보장하지만 데이터의 암호화를 포함하지 않기 때문에 민감한 정보를 Payload에 포함해서는 안된다!


JWE란?

JWE는 JSON Web Encryption의 약자로 데이터를 암호화하여 JWT를 생성하는 방법을 정의한다. JWT에는 암호화가 없지만 JWE는 암호화가 되어있어 Payload를 보호한다.

즉, 데이터의 기밀성을 유지하기 위해서 사용한다!


마찬가지로 JWT와 뭐가 달라? 라고 할 수 있다.

위에서도 얘기했지만 JWT는 내용이 암호화가 되지 않아 누구나 볼 수 있다. 그러나 JWE는 Token의 내용이 암호화되어 보호되며 매우 민감한 데이터를 전송할 때 사용이 된다.

그러나, 암호화 알고리즘에 따라 구현을 할 때 복잡성이 증가할 수 있다는 단점이 존재한다..!


JWE 구조를 살펴보면 다음과 같다!

  • Protected Header
    : 암호화 알고리즘 정보과 키 관리 방법을 포함
  • Encrypted Key
    : 콘텐츠 암호화를 위한 키
  • Initialization Vector (IV)
    : 암호화에 사용되는 초기화 벡터
  • Ciphertext
    : 암호화된 실제 데이터
  • Authentication Tag
    : 무결성 확인을 위한 태그

이 모든 부분은 JWT와 마찬가지로 Base64Url로 인코딩되고, .으로 구분된다.


JWK란?

JWK란 JSON Web Key의 약자로 JSON 포맷으로 암호화 키를 표현하는 표준이다. 키는 공개 키 또는 비밀 키일 수 있으며, JSON 객체 내에 여러 속성을 포함하여 키의 메타데이터와 함께 전달된다.

즉, JWK는 키를 표현하는 형식이다!


이번에도 역시 JWT와 무엇이 다른지 살펴보자.

JWT는 정보를 전송하기 위한 Token이고, JWK는 JWT를 서명하거나 암호화하기 위해 사용되는 키를 표현하는 형식이다! 때문에 JWK는 주로 키 관리와 교환에 사용된다.


JWK 구조를 살펴보면 다음과 같다!

  • kty
    : 키 타입
    ex) RSA, EC
  • use
    : 키 사용 용도
    ex) sig - 서명, enc - 암호화
  • alg
    : 키가 사용되는 알고리즘
    ex) RS256, ES256
  • kid
    : 키 식별자 (Key ID)

어떻게 적용하지?

위에서도 설명을 했지만 다시 한 번 정리하면서 어떻게 적용하는지 살펴보자!

JWT는 정보를 JSON 객체로 표현하여 인코딩된 Token이다. 정보 전달을 위해서 사용이 된다!

JWS는 JWT에 서명을 추가하여 무결성을 보장한다!
JWE는 JWT에 암호화를 하여 기밀성을 보장한다!
JWK는 암호화 키를 표현하여 키 관리를 용이하게 한다!


정리하자면

JWT는 정보를 비밀리에 전달하거나 인증할 때 주로 사용하는 토큰으로 JSON 객체를 이용한다!

JWT와 다른 보안방식을 같이 사용하게 된다면 조금 더 안전하게 사용할 수 있다!

profile
소소한 공부기록

0개의 댓글