JWT 서명 검증 — 이 토큰을 믿어도 되나¶
JWT는 누구나 디코딩해서 내용을 읽을 수 있어요. 그렇다면 왜 위조된 토큰을 못 만들어 낼까요? 바로 서명(signature)을 검증하기 때문이에요. 서명은 토큰이 발급된 뒤 내용이 바뀌지 않았다는 증거이고, 검증은 그 서명이 진짜인지(그리고 만료·수신자 같은 조건을 만족하는지) 확인하는 절차예요. 이 페이지에선 신뢰할 수 있는 토큰인지 따지는 방법을 다룹니다.
개요¶
JWT의 세 번째 부분인 시그니처는 헤더 + 페이로드를 발급자의 키로 서명한 결과예요. 검증하는 쪽은 발급자가 공유한 검증 키로 이 서명을 다시 계산해, 토큰에 적힌 서명과 같은지 비교합니다. 같으면 "내용이 발급자가 만든 그대로"라는 뜻이죠. 다르면 토큰이 도중에 바뀌었거나 위조된 거예요.
핵심 개념¶
서명 알고리즘 두 갈래. 하나의 비밀키로 서명하고 검증하는 대칭 방식(HS256)과, 개인키로 서명하고 공개키로 검증하는 비대칭 방식(RS256 계열)이 있어요.
왜 RS256이 자주 권장될까? 비대칭 방식은 여러 서비스가 공개키만 나눠 쓰면 각자 검증할 수 있어요. 검증 키는 공개돼도 괜찮으니까, 서로 다른 백엔드가 같은 발급자의 토큰을 각자 검증하기 좋아요. 반대로 HS256은 하나의 비밀키를 모든 검증 쪽이 공유해야 해서 키 관리 부담이 커요.
검증할 때 확인해야 할 것들. 서명이 유효한지에 더해, 페이로드의 클레임 조건도 함께 봐야 해요. 대표적으로 만료(exp)를 지났는지, 수신자(aud)가 우리인지, 발급자(iss)가 신뢰하는 대상인지를 점검해요. 서명만 맞다고 토큰을 믿으면, 만료된 토큰이나 남의 서비스용 토큰을 통과시킬 수 있어요.
알고리즘 혼동 공격(algorithm confusion)에 주의. 토큰 헤더에 적힌 알고리즘 이름을 곧이곧대로 받아들이는 서버는, 공격자가 "alg: none"이나 대칭 알고리즘으로 바꿔치기해 서명을 우회할 수 있어요. 그래서 라이브러리를 쓸 때도 발급자와 합의한 알고리즘만 허용하도록 고정하고, 서명이 없는 "none"은 절대 통과시키지 않아야 해요.
검증 키를 어디서 얻나. 검증 키는 발급자가 공유한 곳에서 가져오거나, 공개키 기반이라면 공개키를 가져와요. 단일 서비스면 설정으로, 여러 서비스면 공유 키 저장소로 관리할 수 있어요.
실제 적용(데이터스케쳐스)¶
각 백엔드는 받은 JWT의 서명과 exp·aud·iss 클레임을 함께 검증해요. Spring Security 같은 프레임워크는 이 검증을 필터에서 공통으로 처리해, 서비스마다 검증 방식을 흩어지지 않게 하죠. 검증은 허용 알고리즘을 고정한 상태에서만 이뤄지도록 설정해요.
토큰 검증 라이브러리의 버전과 설정은 보안에 직결되니, "어떤 알고리즘을 허용하는지", "none을 차단하는지"를 코드로 명시해 두는 게 원칙이에요. 이렇게 하면 서비스가 늘어나도 검증 기준이 같아져요.
더 알아보기¶
- 공식 문서 (1차): jwt.io, JWT 알고리즘 (RFC 7518), JSON Web Signature (RFC 7515)
- 큐레이션/블로그 (2차): Auth0 — JWT 검증 가이드