필요한 툴을, 바로 쓸 수 있게

JWT 디코더

JWT를 붙여 넣으면 헤더와 페이로드를 바로 풀어 클레임마다 뜻을 붙이고, 서버가 확인하는 순서대로 형식, 서명, 시간, 발급자·수신자 네 관문을 따라갑니다. 비밀 키나 공개 키(PEM, JWK, JWKS)를 넣으면 서명을 실제로 확인하고, exp까지 남은 시간은 시간선 위에서 초 단위로 줄어듭니다. 토큰과 키는 브라우저 밖으로 나가지 않습니다.

최종 수정 2026-10-22계산은 브라우저 안에서만 처리
예시

토큰과 키는 이 브라우저 안에서만 계산하며 전송하거나 저장하지 않습니다. 운영 비밀 키는 붙여 넣지 않는 편이 안전합니다.

유효 시간

    서명 확인

    내용

    최종 수정 2026-10-22입력값은 저장하지 않습니다

    ROBERIN 기준필요한 툴을,
    바로 쓸 수 있게.
    • 바로 보이는 화면입력 위치와 결과 위치를 또렷하게 둡니다.
    • 결과 먼저핵심 결과를 앞에 두고, 과정은 필요할 때만 보여줍니다.
    • 요구 줄이기가입이나 불필요한 정보 입력 없이 바로 쓰게 합니다.

    JWT 디코딩은 내용을 읽을 뿐이고, 믿어도 되는지는 서명과 시간이 정합니다

    JWT(JSON Web Token)는 점(.) 두 개로 나눈 헤더, 페이로드, 서명 세 구간으로 된 문자열입니다. 앞의 두 구간은 JSON을 Base64url로 옮겨 적은 것이라 키 없이 누구나 풀어 읽을 수 있습니다. 그래서 디코딩해서 내용이 보였다는 사실만으로는 그 토큰이 진짜인지, 지금 써도 되는지 알 수 없습니다. 서버는 서명이 맞는지, 만료 시각(exp)이 지나지 않았는지, 발급자(iss)와 수신자(aud)가 기대한 값인지를 차례로 확인한 뒤에 토큰을 받아들입니다.

    위 도구는 붙여 넣은 토큰을 바로 풀어 헤더와 페이로드의 값과 뜻을 표로 보여 주고, 같은 순서로 네 관문(형식, 서명, 시간, 발급자·수신자)을 따라가며 어디에서 막히는지 표시합니다. 비밀 키나 공개 키(PEM, JWK, JWKS)를 넣으면 서명을 실제로 확인하고, exp까지 남은 시간은 시간선 위에서 초 단위로 줄어듭니다. 토큰과 키는 브라우저 안에서만 계산하며 어디에도 보내지 않습니다.

    JWT를 직접 풀어 봐야 하는 때

    • API가 401 Unauthorized를 돌려줄 때: 거절 이유는 대개 만료(exp), 다른 서비스용 토큰(aud), 키 교체(kid)입니다. 토큰을 붙여 넣으면 네 관문 가운데 어디에서 막히는지 바로 보입니다.
    • 로그인이 예상보다 일찍 풀릴 때: iat와 exp의 차이가 토큰의 수명입니다. 액세스 토큰은 수명을 15분이나 1시간처럼 짧게 두는 경우가 많으므로, 화면의 수명과 남은 시간으로 설정값을 확인할 수 있습니다.
    • OpenID Connect 로그인을 붙일 때: ID 토큰의 iss, aud, nonce, email_verified 같은 값이 기대한 대로 들어왔는지 확인합니다. 공급자의 jwks_uri에서 받은 JSON을 그대로 넣으면 kid가 같은 공개 키로 서명을 확인합니다.
    • 권한이 왜 없는지 찾을 때: scope, roles, groups 같은 클레임에 필요한 권한이 들어 있는지 칩으로 나눠 보여 줍니다. 값의 뜻은 발급 서비스가 정하므로 서버 설정과 함께 비교하세요.
    • 서버 시계와 기기 시계가 다를 때: 발급 직후인데 "아직 사용 전"이나 "만료"가 나온다면 시계 차이일 수 있습니다. 허용 오차를 0초, 60초, 5분으로 바꿔 가며 판정이 어떻게 달라지는지 볼 수 있습니다.
    • 시험용 토큰이 필요할 때: 'JSON 고치기'에서 페이로드를 고치고 비밀 키로 다시 서명하면 원하는 값의 토큰을 만들 수 있습니다. 키 없이 고치면 서명이 맞지 않게 되는 것도 바로 확인할 수 있습니다.

    쓰는 법

    1. 토큰 넣기: 토큰 칸에 JWT를 붙여 넣습니다. Authorization: Bearer … 헤더, 토큰 응답 JSON({"access_token": "…", "id_token": "…"}), 콜백 주소의 #id_token=…처럼 다른 글과 섞여 있어도 토큰만 찾아 읽습니다. 토큰이 여러 개면 칩으로 고릅니다.
    2. 구간 확인: 토큰 글자는 헤더, 페이로드, 서명 색으로 나뉘고 아래 막대에 구간별 바이트 수가 나옵니다. 표의 줄에 마우스를 올리면 그 값이 토큰의 어느 글자에 들어 있는지 강조됩니다.
    3. 시간 확인: 유효 시간 칸에 만료까지 남은 시간, iat·nbf·exp를 기기 시간대로 바꾼 시각, 토큰의 수명이 나옵니다. 서버가 쓰는 라이브러리에 맞춰 허용 오차를 고릅니다.
    4. 서명 확인: alg가 HS256 같은 HS 계열이면 비밀 키를, RS·PS·ES·EdDSA 계열이면 공개 키를 넣습니다. 서버가 기대하는 발급자와 수신자를 넣으면 네 번째 관문까지 확인합니다.
    5. 고치기: '내용'의 'JSON 고치기'를 누르면 헤더와 페이로드를 직접 고칠 수 있습니다. 서명 확인 칸에 비밀 키나 개인 키가 있으면 고친 내용으로 다시 서명한 토큰을 만듭니다.

    점 두 개로 나뉜 세 구간

    헤더와 페이로드는 UTF-8 JSON을 Base64url로 바꾼 값입니다. Base64url은 일반 Base64의 +와 / 대신 -와 _를 쓰고 끝의 =를 빼는 방식(RFC 7515 2절)이라 주소창이나 HTTP 헤더에 그대로 넣을 수 있습니다. 서명은 "헤더.페이로드" 글자 전체를 키로 계산한 바이트를 같은 방식으로 적은 값이므로, 헤더나 페이로드의 한 글자만 바뀌어도 맞지 않게 됩니다. 아래는 비밀 키 demo-secret-for-roberin-jwt-2026으로 만든 HS256 토큰을 나눈 것입니다.

    예시 토큰의 세 구간
    구간토큰 글자풀면글자 수바이트
    헤더eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9{"alg":"HS256","typ":"JWT"}3627
    페이로드eyJzdWIiOiJ1c2VyLTEwMjQiLCJpYXQiOjE3MDQwNjcyMDAsImV4cCI6MTcwNDA2ODEwMH0{"sub":"user-1024","iat":1704067200,"exp":1704068100}7153
    서명5YZB1gnh7IFicIbrPtT-mJoFb3uuYFcYTk84hPIA7RoHMAC-SHA256 값(JSON 아님)4332

    바이트 3개가 글자 4개가 되므로 Base64url 구간은 원래 JSON보다 약 3분의 1 길어집니다. 서명 구간의 길이는 알고리즘이 정합니다. HS256은 32바이트(43글자), RS256은 RSA 키 길이만큼(2048비트 키면 256바이트, 342글자), ES256은 64바이트(86글자)입니다. 구간이 다섯 개라면 암호화된 JWE(RFC 7516)입니다. JWE의 헤더는 읽을 수 있지만 나머지 넷은 받는 쪽 키 없이 풀 수 없습니다.

    자주 보는 클레임과 확인할 점

    페이로드의 각 항목을 클레임이라고 합니다. RFC 7519가 등록한 일곱 개와 OpenID Connect가 정한 이름은 뜻이 정해져 있고, 그 밖의 이름은 발급 서비스가 따로 정한 값(Private Claim)입니다. 표의 '확인할 점'은 토큰을 받는 서버가 해야 하는 일입니다.

    등록된 클레임과 받는 쪽의 확인
    클레임뜻확인할 점
    iss발급자믿는 발급자 값과 글자까지 같아야 합니다. 주소 끝의 /가 하나 달라도 다른 값입니다.
    sub주체(사용자 ID)발급자 안에서만 고유하므로 iss와 묶어서 사용자를 구별합니다.
    aud수신자문자열이나 배열입니다. 자기 이름이 없으면 거절해야 합니다(RFC 7519 4.1.3).
    exp만료 시각지금이 exp와 같거나 늦으면 만료입니다. 시계 차이를 위해 몇 분 이내의 허용 오차를 둘 수 있습니다.
    nbf사용 시작 시각지금이 nbf보다 이르면 아직 받으면 안 됩니다.
    iat발급 시각토큰이 얼마나 오래됐는지 볼 때 씁니다. 그 자체로 만료를 정하지는 않습니다.
    jti토큰 ID이미 쓴 jti를 기록해 두면 같은 토큰의 재사용을 막을 수 있습니다.
    nonce요청 확인값(OIDC)로그인 요청 때 보낸 값과 같아야 합니다. 다르면 다른 로그인의 토큰입니다.
    azp토큰을 받은 앱(OIDC)있으면 자기 client_id와 같은지 확인합니다.
    scope권한 범위공백으로 나눈 목록입니다. 요청한 일에 필요한 범위가 들어 있는지 봅니다.

    exp·nbf·iat 읽는 법과 시계 허용 오차

    세 시각은 모두 1970년 1월 1일 0시(UTC)부터 센 초입니다(RFC 7519의 NumericDate). 같은 순간을 한국 시간으로 적으면 9시간이 더해집니다. 밀리초로 적은 값은 13자리가 되는데, 이것을 초로 읽으면 수만 년 뒤가 되어 토큰이 사실상 끝나지 않습니다. 도구는 이런 값을 찾으면 경고를 붙입니다.

    초 값과 시각
    값UTC한국 시간(UTC+09:00)설명
    17040672002024-01-01 00:00:002024-01-01 09:00:00위 예시 토큰의 iat
    17040681002024-01-01 00:15:002024-01-01 09:15:00예시 토큰의 exp, 수명 900초 = 15분
    20000000002033-05-18 03:33:202033-05-18 12:33:20열 자리 초 값
    1704067200000(초로 읽으면 55969년)-밀리초로 잘못 적은 값, 1000으로 나눠야 함

    서버의 시계와 발급 서버의 시계는 몇 초에서 몇 분까지 어긋날 수 있습니다. RFC 7519는 exp와 nbf를 확인할 때 "보통 몇 분을 넘지 않는" 작은 허용 오차를 두어도 된다고 적습니다. 실제 기본값은 라이브러리마다 다르므로, 같은 토큰이 어떤 서버에서는 받아들여지고 어떤 서버에서는 거절될 수 있습니다.

    라이브러리별 시계 허용 오차 기본값(2026년 10월 원본 코드 기준)
    라이브러리설정 이름기본값
    PyJWT(Python)leeway0초
    jsonwebtoken(Node.js)clockTolerance0초
    Spring Security(Java)JwtTimestampValidator clockSkew60초
    Microsoft.IdentityModel(.NET)TokenValidationParameters.ClockSkew5분(300초)

    도구의 판정은 jsonwebtoken과 같습니다. 지금 시각(초 단위로 버림)이 exp + 허용 오차와 같거나 늦으면 만료, nbf가 지금 + 허용 오차보다 늦으면 사용 전입니다. 만료 시각이 지났지만 허용 오차 안이면 시간 관문은 통과로 두고 남은 여유 시간을 보여 줍니다.

    서명 확인: 알고리즘마다 필요한 키

    헤더의 alg는 어떤 방식으로 서명했는지 적은 이름입니다. 받는 쪽이 이 값을 그대로 믿으면 안 되므로, 서버는 허용할 알고리즘을 미리 정해 두고 그 밖의 값은 거절해야 합니다(RFC 8725 3.1). 도구는 alg에 맞는 키 종류를 안내하고, 맞지 않는 키를 넣으면 이유를 알려 줍니다.

    알고리즘 계열별 확인 키
    alg확인에 쓰는 키넣을 수 있는 형식규칙
    HS256·HS384·HS512만든 쪽과 같은 비밀 키글자 그대로, Base64 값, JWK(kty oct)키 길이가 해시 길이 이상이어야 함(HS256은 256비트, RFC 7518 3.2)
    RS256·RS384·RS512RSA 공개 키PEM 공개 키, PKCS#1, X.509 인증서, JWK, JWKS2048비트 이상(RFC 7518 3.3)
    PS256·PS384·PS512RSA 공개 키RS 계열과 같음RSA-PSS, 소금 길이 = 해시 길이(RFC 7518 3.5)
    ES256P-256 공개 키PEM, 인증서, JWK(kty EC), JWKS서명은 R과 S를 이은 64바이트(RFC 7518 3.4)
    ES384P-384 공개 키ES256과 같음서명 96바이트
    ES512P-521 공개 키ES256과 같음서명 132바이트(곡선 이름은 P-521)
    EdDSA·Ed25519Ed25519 공개 키PEM, JWK(kty OKP)RFC 9864(2025년 10월)는 EdDSA 대신 Ed25519라는 이름을 쓰도록 정함

    개인 키를 넣어도 공개 키를 꺼내 확인하지만, 확인에는 공개 키만 있으면 됩니다. 비밀 키를 복사할 때 끝에 줄바꿈이 붙는 경우가 많아서, 넣은 그대로는 맞지 않고 앞뒤 공백을 뺐을 때 맞으면 그렇게 알려 줍니다. 서명이 DER 형식(0x30으로 시작)인 ES 토큰은 다른 라이브러리가 잘못 만든 것이므로 원인을 따로 표시합니다.

    검문 경로가 서버의 확인 순서와 같은 이유

    RFC 7519 7.2절은 JWT를 받을 때 구간을 나누고, Base64url과 JSON을 풀고, 서명을 확인하는 순서를 적고 있습니다. 어느 단계에서든 실패하면 토큰을 거절해야 합니다. 그 위에 RFC 8725는 iss가 있으면 서명 키가 그 발급자의 것인지 확인하고(3.8), 한 발급자가 여러 서비스에 토큰을 준다면 aud가 없거나 자기 것이 아닐 때 거절하라고(3.9) 정합니다. 도구의 네 관문은 이 순서를 그대로 따르며, 처음 막힌 관문의 이유를 판정 줄에 적습니다. 서명을 확인하지 않은 상태에서는 다른 관문을 통과해도 "아직 확인하지 않음"으로 남겨 둡니다.

    권한이 맞는지, 이미 로그아웃한 세션인지, 같은 jti를 다시 썼는지는 토큰만으로는 알 수 없습니다. 이런 조건은 서버가 가진 기록과 설정으로 확인하므로, 네 관문을 모두 통과했다는 뜻은 "토큰 자체의 조건은 맞는다"는 것입니다.

    JSON 고치기와 다시 서명

    'JSON 고치기'에서 헤더나 페이로드를 바꾸면 도구가 새 토큰을 만들어 토큰 칸에 넣습니다. 서명 확인 칸에 HS 비밀 키나 RS·PS·ES·Ed25519 개인 키(PKCS#8, PKCS#1, EC 개인 키, d가 있는 JWK)가 있으면 그 키로 다시 서명합니다. 공개 키만 있거나 키가 없으면 원래 서명을 그대로 붙이므로 서명 관문이 불일치로 바뀝니다. 예시의 '내용을 바꾼 토큰'이 바로 이 경우입니다. role 값을 user에서 admin으로 바꿨지만 서명은 그대로라서, 비밀 키로 확인하면 바로 드러납니다.

    'iat를 지금으로, exp는 15분 뒤·1시간 뒤·1일 뒤' 단추는 시험용 토큰의 시각을 한 번에 바꿉니다. nbf가 있으면 nbf도 지금으로 맞춥니다. 고친 JSON은 공백만 지워 한 줄로 만들기 때문에 키 순서와 숫자 표기는 적은 그대로 남습니다.

    자주 틀리는 경우와 알려진 공격

    • alg none을 받아 주는 서버: 서명 없는 토큰은 누구나 만들 수 있습니다. 대소문자만 바꾼 None, NONE을 받아 준 라이브러리도 있었으므로 허용 목록으로 막아야 합니다(RFC 8725 2.1).
    • RS256 토큰을 HS256으로 바꿔치기: 공격자가 alg를 HS256으로 바꾸고 서버의 공개 키를 HMAC 비밀 키로 써서 서명하는 방식입니다. 키 하나를 알고리즘 하나에만 쓰면 막힙니다. 도구는 HS 토큰에 공개 키를 넣으면 이 형태라고 알립니다.
    • 외우기 쉬운 비밀 키: HS256 토큰 하나만 손에 넣으면 비밀 키를 사전 공격으로 찾을 수 있습니다. 비밀 키는 무작위로 만들고(RFC 8725 3.5), 길이는 해시 길이 이상이어야 합니다. HS256이라면 32바이트 이상입니다(RFC 7518 3.2).
    • aud를 확인하지 않는 서버: 같은 발급자가 다른 서비스에 준 토큰을 그대로 받아 버립니다. ID 토큰을 API 접근에 쓰는 실수도 같은 이유로 막아야 합니다.
    • kid·jku를 그대로 쓰는 키 찾기: kid를 파일 경로나 SQL에 그대로 넣거나, 헤더의 jku 주소에서 키를 받아 오면 공격자가 고른 키로 확인하게 됩니다(RFC 8725 3.10).
    • 페이로드에 넣은 개인 정보: 서명된 JWT는 암호화가 아닙니다. 이메일, 전화번호를 넣으면 토큰이 지나가는 로그와 브라우저 어디에서나 읽힙니다.
    • 복사할 때 붙은 글자: Bearer, 따옴표, 줄바꿈이 함께 들어가면 서버가 토큰을 읽지 못합니다. 도구는 이런 글자를 떼고 읽은 뒤 무엇을 뗐는지 적습니다.

    한계와 주의

    • JWE(다섯 구간)는 헤더만 읽고 복호화하지 않습니다. 중첩 JWT, b64가 false인 토큰(RFC 7797), JSON 직렬화 형식의 JWS도 읽지 않습니다.
    • 서명 확인은 브라우저의 Web Crypto로 합니다. ES256K와 Ed448은 확인할 수 없고, Ed25519는 지원하지 않는 오래된 브라우저에서 확인할 수 없다고 표시합니다.
    • jku·x5u 주소나 공급자의 jwks_uri에서 키를 받아 오지 않습니다. 공개 키는 직접 붙여 넣어야 하며, 이것은 토큰을 외부로 보내지 않기 위한 선택입니다.
    • 시간 판정은 이 기기의 시계를 기준으로 합니다. 기기 시계가 틀리면 남은 시간과 판정도 그만큼 틀립니다.
    • 네 관문을 통과해도 권한, 로그아웃 여부, 재사용 여부는 서버만 알 수 있습니다. 운영 중인 비밀 키와 실제 사용자 토큰은 가능하면 붙여 넣지 말고, 시험용 키와 토큰으로 확인하세요.

    기준: JWT·JWS·JWE·JWK·JWA 규칙은 RFC 7519·7515·7516·7517·7518, 보안 권고는 RFC 8725, Ed25519 이름은 RFC 9864, ID 토큰 클레임은 OpenID Connect Core 1.0, 허용 오차 기본값은 각 라이브러리의 원본 코드를 2026년 10월 22일에 확인했습니다. 표의 토큰과 시각은 이 도구와 Python PyJWT 2.13으로 같은 값을 확인했습니다.

    출처

    자주 묻는 질문

    JWT를 디코딩하면 그 토큰이 유효한지 알 수 있나요?

    아닙니다. 헤더와 페이로드는 Base64url이라 누구나 풀 수 있으므로, 내용이 보인다는 것은 형식이 맞다는 뜻일 뿐입니다. 유효한지는 서명이 맞는지, exp가 지나지 않았는지, iss와 aud가 기대한 값인지까지 확인해야 알 수 있습니다. 위 도구의 네 관문이 이 순서를 그대로 따릅니다.

    JWT 페이로드는 암호화되어 있나요?

    서명된 JWT(점 두 개, 세 구간)는 암호화되어 있지 않습니다. 서명은 내용이 바뀌지 않았다는 것만 보장하고 내용을 숨기지는 않습니다. 이메일이나 전화번호처럼 남이 보면 안 되는 값은 페이로드에 넣지 않거나, 암호화된 JWE를 써야 합니다.

    exp가 아직 지나지 않았는데 401이 나는 이유는 무엇인가요?

    서명 키가 바뀌어 kid에 맞는 공개 키가 없거나, aud가 그 API의 이름과 다르거나, iss가 서버 설정과 한 글자라도 다를 때 거절됩니다. 서버 시계가 빠르면 만료 직전 토큰이 먼저 만료로 판정되기도 합니다. 로그아웃 등으로 서버가 토큰을 따로 폐기한 경우는 토큰만 보고는 알 수 없습니다.

    HS256 비밀 키를 넣었는데 서명 불일치가 나옵니다.

    먼저 서버 설정의 비밀 키가 평범한 글자인지 Base64 값인지 확인하고 '글자 그대로'와 'Base64 값'을 바꿔 보세요. 복사할 때 붙은 줄바꿈은 도구가 빼고 다시 확인합니다. 그래도 맞지 않으면 다른 환경(개발·운영)의 키이거나, 서명 뒤에 헤더나 페이로드가 바뀐 토큰입니다.

    RS256 토큰을 확인할 공개 키는 어디에서 구하나요?

    OpenID Connect 공급자라면 발급자 주소 뒤에 /.well-known/openid-configuration을 붙인 문서의 jwks_uri에 공개 키 목록(JWKS)이 있습니다. 그 JSON을 통째로 붙여 넣으면 도구가 토큰 헤더의 kid와 같은 키를 골라 확인합니다. PEM 공개 키나 X.509 인증서를 넣어도 됩니다.

    토큰을 여기에 붙여 넣어도 안전한가요?

    토큰과 키는 이 브라우저 안에서만 계산하며 서버로 보내거나 저장하지 않습니다. 다만 운영 중인 액세스 토큰은 만료 전까지 실제로 쓸 수 있는 열쇠이므로, 화면을 공유하거나 캡처할 때 조심하고 가능하면 시험용 토큰으로 확인하세요.

    exp 숫자는 어떤 단위인가요?

    1970년 1월 1일 0시(UTC)부터 센 초입니다. 1704067200은 2024년 1월 1일 0시 UTC, 한국 시간으로는 같은 날 오전 9시입니다. 13자리 값은 밀리초로 잘못 적은 것이라 초로 읽으면 수만 년 뒤가 되므로 1000으로 나눠야 합니다.

    점이 네 개인(구간이 다섯 개인) 토큰은 무엇인가요?

    암호화된 JWE입니다. 첫 구간인 헤더만 읽을 수 있고 나머지는 받는 쪽의 키로 복호화해야 내용이 보입니다. 이 도구는 JWE 헤더의 alg와 enc, 각 구간의 바이트 수까지만 보여 줍니다.