JWT 디코딩과 검증: 읽히는 내용과 믿을 수 있는 내용

JWT인증개발 도구

JWT 디코딩은 내용을 읽는 단계입니다

JWT 디코딩 결과에 "role": "admin"이 보인다고 관리자 권한이 확인된 것은 아닙니다. 디코딩은 토큰에 적힌 내용을 읽는 작업입니다. 그 내용을 누가 만들었고 중간에 바뀌지 않았는지는 별도로 확인해야 합니다.

이 글은 JWT 도구에서 다루는 서명된 JWT를 기준으로 합니다. JWT에는 암호화된 형태도 있지만, 흔히 보는 서명 토큰의 header와 payload는 읽을 수 있는 데이터입니다. 서명은 내용을 숨기는 기능이 아닙니다. RFC 7519의 JWT 구조 설명

단계확인하는 것이 단계만으로 알 수 없는 것
디코딩header와 payload에 적힌 값발급자의 신뢰성, 위변조 여부
서명 검증선택한 알고리즘과 키로 서명이 맞는지서비스가 이 토큰을 받아야 하는지
서비스 검증발급자·수신자·시간 조건·권한 등 서비스 규칙다른 서비스의 정책까지 자동으로 확인하지는 않음

세 부분을 나눠 보면 역할이 보입니다

서명 토큰은 점으로 구분한 세 부분을 사용합니다. 앞의 두 부분을 Base64url로 해석하면 JSON header와 payload를 읽을 수 있습니다.

encoded-header.encoded-payload.signature

예제 header는 다음처럼 만듭니다. alg는 서명 알고리즘을 나타내고, 여기서는 같은 비밀 값을 사용하는 HS256을 선택합니다.

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

payload에는 실제 계정 정보 대신 시험용 값만 넣습니다.

{"sub":"demo-user","role":"viewer"}

이 값은 공개 예제입니다. 실제 이메일, 세션 토큰, 개인 키를 예제에 섞지 마세요. JSON 문법이 잘못되면 먼저 JSON 포맷터에서 괄호와 따옴표를 확인할 수 있습니다.

같은 키와 다른 키로 검증해 봅니다

JWT 도구에서 HS256을 고르고 위 header와 payload를 입력합니다. 서명 키에는 아래의 공개된 테스트 문자열을 사용해 서명합니다. 운영 환경에 사용할 비밀 값이 아닙니다.

demo-only-secret-not-for-production

생성된 토큰은 디코딩하면 subdemo-user, roleviewer로 보입니다. HS256은 같은 비밀 키 입력칸을 서명과 검증에 사용합니다. 같은 문자열로 검증하면 통과하고, 키 끝에 -wrong을 붙여 다시 실행하면 서명 검증이 실패합니다.

시험JWT 디코딩 결과검증 결과
원래 토큰 + 같은 키예제 클레임을 읽을 수 있음통과
원래 토큰 + 다른 키같은 클레임을 읽을 수 있음실패
payload를 바꾸고 원래 서명을 유지바꾼 JSON을 읽을 수 있음실패

마지막 행은 내용을 읽는 것과 서명을 확인하는 것이 다르다는 예입니다. payload를 수정한 뒤 다시 서명하면 새 토큰이 만들어집니다. 그 경우는 기존 서명의 위변조 검증과 다른 시험입니다.

서명 이후에도 서비스의 기준이 필요합니다

실제 서비스에서는 허용할 알고리즘과 키를 신뢰할 수 있는 설정으로 정해야 합니다. 받은 토큰이 주장하는 알고리즘을 그대로 신뢰해 정책을 바꾸면 안 됩니다. 발급자 iss, 대상 서비스 aud, 만료 exp와 사용 시작 nbf 등 필요한 조건도 확인합니다. RFC 8725의 검증 권고

현재 도구는 선택한 알고리즘으로 jose의 JWT 검증을 수행합니다. 토큰에 시간 클레임이 있으면 만료 등으로 실패할 수 있지만, 사용자의 서비스가 기대하는 발급자·수신자나 계정의 폐기·권한 상태까지 알지는 못합니다. 위 최소 예제에는 시간 클레임도 넣지 않았습니다. 서비스용 인증 토큰 설계 예제로 받아들이면 안 되는 이유입니다.

운영 토큰을 공유하는 대신 예제처럼 별도 데이터를 만들어 확인하세요. 서명 오류를 살펴볼 때는 먼저 선택한 알고리즘과 키를 점검하고, 통과한 뒤에도 서비스가 요구하는 조건을 따로 대조하면 됩니다.