블로그로
tutorial 2026-06-14

토큰을 절대 보내지 않는 프라이버시 안전 JWT 디버거 (2026)

토큰을 절대 보내지 않는 프라이버시 안전 JWT 디버거

밤 11시에 OAuth 흐름을 디버깅하고 있는데, 클레임이 올바르게 설정되었는지 확인하기 위해 네트워크 탭에서 JWT를 잡고, Google이 처음 표시한 JWT 디코더에 붙여넣고, 잠시 후 프로덕션 ID 공급자가 서명한 작동하는 액세스 토큰을 제3자 웹사이트에 방금 주었다는 것을 기억합니다 —— 고객 계정에 로그인하고, 내부 API를 호출하고, 토큰의 범위가 허용하는 무엇이든 읽을 수 있는 완전한 능력이 있습니다.

공개 웹의 거의 모든 인기 있는 JWT 디코더 —— jwt.io, jwtdecoder.net, 수십 개의 클론 —— 는 내부를 보여주기 전에 붙여넣은 토큰을 서버에 게시합니다. 그들의 프라이버시 페이지는 "저장하지 않습니다"라고 말하는데 사실일 수도 있지만 토큰은 여전히 공개 인터넷을 가로지르고, 제3자 HTTPS 엔드포인트에 도달하며, 일정 보존 기간 동안 그들의 HTTP 액세스 로그에 살았습니다. 프로덕션 토큰의 경우 그것은 공개할 가치가 있는 보안 사건입니다.

이 가이드는 JWT가 실제로 어떻게 작동하는지, JWT를 "디코딩"하는 것이 실제로 무엇을 하는지, 그리고 브라우저 탭에서 100% 실행되는 **Ai2Done의 JWT Decoder**를 사용하여 안전하게 디버깅하는 방법을 설명합니다.

TL;DR

  • JWT는 점으로 구분된 세 개의 base64 문자열일 뿐입니다 —— 헤더, 페이로드, 서명.
  • JWT를 "디코딩"하는 것은 처음 두 부분을 base64 디코딩하는 것일 뿐입니다. 서명 검증이 아닙니다.
  • 대부분의 온라인 JWT 디코더는 토큰을 그들의 서버에 게시합니다. 그들이 로그하지 않는다고 말해도 토큰은 여전히 기기를 떠나 어딘가의 액세스 로그에 들어갔습니다.
  • Ai2Done JWT Decoder는 브라우저에서 완전히 실행됩니다 —— 토큰이 탭을 떠나지 않습니다.
  • 실제 권한이 있는 프로덕션 토큰의 경우 이것이 유일한 안전한 패턴입니다. 프로덕션 JWT를 제3자 도구에 붙여넣는 모든 행위를 누군가에게 비밀번호를 건네준 것처럼 다루십시오.

이것이 보이는 것보다 어려운 이유

JWT(JSON Web Token, RFC 7519)는 구조적으로 사소합니다:

eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiIxMjMiLCJleHAiOjE3NTAwMDAwMDB9.dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk

.로 구분된 세 부분:

  1. 헤더(eyJhbGciOiJIUzI1NiJ9) —— 서명 알고리즘을 설명하는 base64 인코딩 JSON {"alg":"HS256"}.
  2. 페이로드(eyJzdWIi...) —— 실제 클레임(sub, exp, 사용자 정의 필드)이 있는 base64 인코딩 JSON.
  3. 서명(dBjftJeZ...) —— 무결성을 검증하는 데 사용되는 header.payload에 대한 HMAC 또는 RSA/ECDSA.

JWT를 "디코딩"하는 것은 내부의 JSON을 읽기 위해 1부와 2부를 base64 디코딩하는 것을 의미합니다. 이것은 비밀 키, 네트워크 호출, 서버가 필요하지 않습니다. 5줄 JavaScript 함수입니다. 그러나 온라인 JWT 디코더의 99%는 토큰을 백엔드를 통해 왕복하기를 고집하며, 이는 토큰이 들어간다는 것을 의미합니다:

  • 서버의 HTTPS 종료 로그
  • 리버스 프록시 액세스 로그
  • 가능하게는 응용 프로그램 로그(구현 방식에 따라)
  • CDN의 엣지 로그(Cloudflare, Fastly 등)
  • 페이지에 로드된 파트너 광고 네트워크, 오류 추적 서비스 또는 분석 공급자의 해당 로그

운영자 측의 최선의 의도에도 불구하고 프로덕션 토큰은 이제 7일에서 "영원"까지의 보존 기간 동안 2-3개의 다른 회사에 걸쳐 4-6개의 다른 로그 파일에 지속됩니다. 그러한 대상 중 어느 것이든 손상시키는 결심된 공격자는 고객의 리소스에 대한 작동하는 베어러 토큰을 가지고 있습니다.

이것은 편집증이 아닙니다. 프로덕션 자격 증명을 처리하는 모든 사람을 위한 표준 위협 모델링입니다.

방법 1: Ai2Done JWT Decoder(브라우저 측, 올바른 방법)

**Ai2Done JWT Decoder**는 브라우저 탭에서 실행되는 200줄의 바닐라 JavaScript입니다. 토큰을 붙여넣고, 내부를 보고, 탭을 닫으면 토큰이 영원히 사라집니다. 흐름:

  1. 어떤 브라우저에서든 /tools/jwt_decoder를 엽니다.
  2. 입력 영역에 JWT를 붙여넣습니다.
  3. 디코딩된 헤더와 페이로드가 즉시 나타납니다 구문 강조 JSON 패널에.
  4. 선택적으로 서명 비밀(HS256) 또는 공개 키(RS256)를 붙여넣어 로컬에서 서명을 검증하십시오. 검증도 클라이언트 측에서 완전히 실행됩니다.

기본 제공되는 것:

  • 알고리즘과 키 ID가 있는 헤더 디코딩
  • 모든 사용자 정의 클레임과 표준 클레임(iss, sub, aud, exp, nbf, iat, jti)이 있는 페이로드 디코딩
  • 사람이 읽을 수 있는 타임스탬프 —— exp: 1750000000도 "47분 후"로 표시되어 토큰이 만료되었거나 만료에 가까운지 즉시 볼 수 있음
  • 클레임 검증 경고 —— exp가 과거이면 필드가 빨간색으로 강조됨; aud가 예상 값과 일치하지 않으면 즉시 비교를 위해 예상 aud를 붙여넣을 수 있음
  • 서명 검증 —— HS256 비밀, RS256 공개 키(PEM) 또는 JWKS URI를 붙여넣으면 도구가 서명이 유효한지 알려줍니다. 검증은 Web Crypto API를 사용하여 브라우저 내에서 완전히.

전체 번들은 ~40 KB입니다. 모든 기기에서 <1초에 로드되고, 일단 캐시되면 오프라인에서 작동하며, 초기 페이지 로드 후 네트워크 호출이 0입니다.

방법 2: 터미널의 5줄 스크립트

이미 터미널에서 작업하는 개발자의 경우 가능한 가장 간단한 JWT 디코더는 한 줄 bash입니다:

echo "YOUR_JWT_HERE" | cut -d. -f2 | base64 -d 2>/dev/null | jq .

이것은:

  1. JWT를 cut에 파이프하여 두 번째 부분(페이로드)을 잡습니다
  2. base64 디코딩합니다(2>/dev/null은 패딩 경고를 침묵시킴)
  3. jq로 예쁘게 인쇄합니다

헤더의 경우 f2f1로 교체하십시오. 서명 검증의 경우 실제 라이브러리를 사용하십시오 —— python -c "import jwt; print(jwt.decode(...))" 또는 언어의 동등한 것. bash에서 HMAC-SHA256 검증을 구현하려고 시도하지 마십시오.

이것은 "이미 서버에 SSH되어 있고 지금 토큰을 검사해야 합니다"에 대한 올바른 답입니다. 이미 브라우저에 있다면 과한 일입니다.

방법 3: 네이티브 macOS / Windows 앱

브라우저 도구를 싫어하는 사람들을 위해 여러 오프라인 전용 JWT 디코더가 있습니다:

  • macOS: JWT Inspector(무료, App Store에서)
  • Windows: IDESoft의 JWT Decoder(무료, MS Store에서)
  • 크로스 플랫폼: VS Code 확장 "JWT Debugger"(편집기 내에서 작동)

모두 네트워크 요청 없이 기기에서 완전히 실행됩니다. 워크플로우에 맞는 것을 선택하십시오.

어떻게 빌드했는지(기술적 심층 분석)

Ai2Done JWT Decoder는 의도적으로 최소화되었습니다:

  • 프레임워크 없음 —— 바닐라 JS, ~200줄, ~40 KB gzip 압축. 3G 연결에서도 즉시 로드.
  • 분석 없음, 텔레메트리 없음 —— 디자인에 의해 얼마나 많은 사람이 사용하는지조차 모릅니다. 페이지 뷰는 경로 수준(/tools/jwt_decoder가 X 방문을 받음)에서 기록되지만 토큰 파생 정보로는 절대 기록되지 않습니다.
  • base64url 안전 기본적으로 —— JWT는 base64의 URL 안전 변형(+/ 대신 -_)을 사용합니다; 둘 다 처리합니다.
  • 서명 검증을 위한 Web Crypto —— crypto.subtle.verify()는 HMAC-SHA256/384/512와 RS256/384/512를 네이티브로 지원합니다. ES256/384(ECDSA)도 현대 브라우저에서 작동합니다. PS256(RSA-PSS)은 일부 오래된 브라우저에 부족하기 때문에 작은 JS shim이 필요합니다.
  • JWKS 지원 —— JWKS URI(예: https://accounts.google.com/.well-known/jwks.json)를 붙여넣으면 도구가 JWK 세트를 가져오고, 토큰의 kid와 일치하는 키를 찾고, 서명을 검증합니다. 가져오기는 우리를 통해서가 아니라 브라우저에서 IdP로 직접 발생합니다.

플래깅할 가치가 있는 한 가지 디자인 결정: "JWT 서명" 기능을 의도적으로 제공하지 않습니다. 도구는 읽기 전용입니다. 서명에는 비밀 키가 필요하며 사용자가 HMAC 비밀이나 RSA 개인 키를 웹 앱에 붙여넣는 습관을 들이는 것을 원하지 않습니다. 응용 프로그램 코드의 실제 라이브러리로 토큰을 서명하십시오; 나온 것을 검증하기 위해 이 도구를 사용하십시오.

FAQ

Q: JWT를 "디코딩"하는 것 자체가 보안 위험입니까? A: 아니요 —— 헤더와 페이로드를 base64 디코딩하면 발급자가 거기에 넣기로 선택한 것만 드러냅니다. JWT 사양은 명시적입니다: 페이로드는 base64 인코딩되며 암호화되지 않습니다. 토큰을 가진 모든 사람이 내부를 읽을 수 있습니다. 실제 위험은 토큰 자체가 누출되도록 하는 것입니다. 토큰은 베어러 자격 증명이기 때문입니다 —— 가진 사람이 사용할 수 있습니다.

Q: 내 토큰의 exp가 과거이지만 API는 여전히 수락합니다. 왜죠? A: 몇 가지 가능한 이유: (1) 서버가 nbfiat와 같은 다른 타임스탬프 클레임을 확인하고 exp를 무시함, (2) 서버에 시계 비스듬함이 있고 만료 후 N분까지의 토큰을 수락함, (3) 토큰 유형이 실제로 액세스 토큰만큼 빨리 만료되지 않는 리프레시 토큰임, 또는 (4) API에 진정으로 버그가 있음. IdP의 검증 정책을 확인하십시오.

Q: IdP의 공개 키 없이 서명을 어떻게 검증합니까? A: 디자인에 의해 할 수 없습니다 —— 그것이 전체 요점입니다. 서명은 토큰이 서명 비밀을 알고 있는 누군가에 의해 발급되었음을 증명합니다. 공개 키(RS256용) 또는 공유 비밀(HS256용)이 없으면 무결성을 검증할 수 없습니다. 디코더가 "검증되지 않음 —— 검증하려면 키를 제공하십시오"라고 알려줄 것입니다. 이것이 올바른 동작입니다.

Q: 도구가 일부 클레임을 표준으로 표시하고 다른 것을 사용자 정의로 표시하는 이유는 무엇입니까? A: RFC 7519는 표준 클레임 이름 세트를 예약합니다: iss, sub, aud, exp, nbf, iat, jti. 다른 모든 것은 사용자 정의입니다(예: name, email, roles, 응용 프로그램 특정 클레임). 디코더는 RFC 정의 의미와 함께 표준 클레임을 강조하고 다른 모든 것을 자유롭게 형성된 JSON으로 다룹니다.

Q: 암호화된 JWE 토큰을 디코딩할 수 있습니까? A: 해독 키 없이는 안 됩니다. JWE(JSON Web Encryption, RFC 7516)는 진정으로 암호화되어 있으므로 페이로드는 키 없이는 불투명합니다. 도구는 헤더의 enc 클레임을 기반으로 JWE 대 JWS를 감지하고 키 없이 암호화된 토큰을 디코딩할 수 없다고 알려줍니다(그리고 키 붙여넣기를 제공하지 않습니다. 그것은 웹 도구가 아니라 자신의 코드에서 발생해야 하는 민감한 작업이기 때문입니다).

Q: 도구가 오프라인에서 작동합니까? A: 예. 첫 방문 후 도구는 브라우저의 HTTP 캐시에 있고 인터넷 액세스 없이 작동합니다 —— 에어갭 환경에서 토큰을 디버깅하거나 네트워크가 다운된 경우 유용합니다.

지금 시도

낯선 사람에게 주지 않고 JWT를 디버깅하십시오:

JWT Decoder 열기 →

붙여넣고, 보고, 닫으십시오. 토큰이 탭을 떠나지 않습니다.

관련 읽기


최종 업데이트 2026-06-14. JWT Decoder는 브라우저 탭에서 100% 실행됩니다 —— 토큰은 기기를 떠나지 않습니다. 서버 로그가 없고, 토큰 콘텐츠에 대한 분석이 없으며, 탭을 닫은 후 디코딩된 토큰을 검색할 방법이 없습니다.