JWT 토큰은 어떻게 검증 할까? 그리고 JWT는 대칭키와 비대칭키 중 어떤 방식을 사용할까?
결론 부터 말하자면 서명을 통해 검증하고 대칭키와 비대칭키를 모두 사용할 수 있다.
JWT란
JWT (JSON Web Token)는 웹 애플리케이션에서 사용자 인증 및 권한 부여를 위해 사용되는 JSON 기반의 토큰 이다.
JWT의 구조
JWT는 Header, Payload, Signature 3 부분으로 이루어저 있다.
- 헤더 (Header): 토큰의 타입(JWT)과 사용된 서명 알고리즘(예: HMAC SHA256, RSA 등)을 지정한다.
- 페이로드 (Payload): 토큰에 담길 정보를 포함하는 부분이다. 보통 사용자의 ID, 권한, 토큰의 만료 시간 등과 같은 클레임(Claims)을 포함한다.
- 서명 (Signature): 헤더와 페이로드의 정보를 결합하여 비밀 키를 사용해 서명한 부분이다. 서명을 통해 데이터의 무결성을 보장하고, 서버는 해당 토큰이 변조되지 않았음을 확인할 수 있다.
JWT는 Header와 Payload를 Base64Url 방식으로 인코딩 하고 합친 뒤 암호화 알고리즘을 통해 Signature를 생성한다.
즉, Header와 Payload를 비밀키로 암호화 한것이 Signature이다. (정확히는 암호화가 아니라 해시화 이다.)
Header = {
"alg": "HS256",
"typ": "JWT"
}
Payload = {
"id": "476183",
"name": "InGyu"
}
// header와 payload를 base64UrlEncode로 인코딩 하고 "."으로 합침
data = base64UrlEncode(header) + "." + base64UrlEncode(payload)
// 해당 data를 my-secret-key로 암호화 한다.
Signature = HMACSHA256(data, my-secret-key)
jwt = eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9
.eyJzdWIiOiIxMjM0NTY3ODkwIiwibmFtZSI6IkpvaG4gRG9lIiwiaWF0IjoxNTE2MjM5MDIyfQ
.SflKxwRJSMeKKF2QT4fwpMeJf36POk6yJV_adQssw5c
이렇게 생성된 토큰에서 Header와 Payload는 단순히 Base64Url 방식으로 인코딩 되어 있는 것이기 때문에
토큰의 Header와 Payload를 Base64Url 방식으로 인코딩하면 Header와 Payload 정보를 얻을수있다.
JWT 검증
서버는 사용자가 보낸 토큰의 Payload를 통해 사용자의 정보를 읽을 수 있다. 해당 토큰이 유효한지는 어떻게 판단할까?
토큰의 Signature 부분은 Header와 Payload를 my-secret-key로 서명한 값이다.
즉, 서버가 받은 토큰의 Header와 Payload를 다시 my-secret-key로 서명하여 생성된 Signature의 값이 동일하다면, 해당 토큰은 위조 되지 않은 정상적인 토큰임을 의미한다.
대칭키와 비대칭키
그렇다면 JWT는 대칭키와 비대칭키 중 어떤 방식을 사용할까?
위 예시에서 서버는 my-secret-key로 서명하여 토큰을 생성하고 이를 사용자에게 전달했다. 그리고 사용자는 이 토큰을 사용하며, 서버에서 토큰을 검증할 때 my-secret-key로 다시 서명하여 생성된 Signature 값을 비교하여 검증했다.
현재 하나의 같은 키로 생성과 검증을 하고 있으며 실제로 프로젝트를 진행하며 JWT를 구현할 때, 설정 파일에 키 값을 하나만 넣어두고 사용했었다. 그래서 당연히 대칭키 방식이라고 생각했다.
하지만 JWT는 대칭키와 비대칭키 모두 사용 가능하다.


- 단일 서버, 속도 중시 → 대칭키
- 간단하고 빠른 처리 속도가 필요한 환경에서 적합.
- 내부 환경에서만 키를 안전하게 관리할 수 있다면 대칭키가 효율적.
- 다중 서버, 보안과 확장성 중시 → 비대칭키
- 키를 외부에 공유하지 않아도 되는 구조로, 신뢰성과 확장성이 뛰어남.
- 클라이언트-서버 간, 다중 서버 통신에서 적합.
즉, 상황에 맞춰 알고리즘을 선택하고, 대칭키와 비대칭키 중 어떤 것을 사용할지 결정하면 된다.
'Java , Spring > Spring' 카테고리의 다른 글
| [Spring Cloud] MSA 서버 간 호출방식 비교 (RestTemplate, FeignClient, WebClient, RestClient) (1) | 2025.02.08 |
|---|---|
| [Spring Cloud] Spring Cloud Gateway (그리고 Zuul 와 Netty) (2) | 2025.01.21 |
| [Spring] Spring Security 예외를 @ControllerAdvice에서 처리하기 (0) | 2024.12.13 |
| [Spring] CS 스터디 - 3주차 Spring & Network (1) | 2024.08.11 |
| [Spring] 선착순 쿠폰 동시성 문제 해결하기 (메세지큐 적용) (0) | 2024.06.26 |
댓글