본문 바로가기
모의해킹/웹모의해킹

🔐 JWT 토큰 구조와 검증 방식

by 러브러브뿅뿅 2025. 12. 9.
728x90

JWT(Json Web Token)는 로그인 이후 인증 상태를 유지하기 위해 사용되는 대표적인 토큰 기반 인증 방식이다.
특히 API 서버, 모바일 앱, SPA 환경에서 널리 쓰인다.

이 글에서는 JWT의 내부 구조, signature가 어떻게 생성/검증되는지, 그리고 모의해킹 관점에서 주의해야 할 부분까지 정리한다.


1) JWT의 기본 구조

 

JWT는 아래 3가지 파트로 구성된다:

HEADER.Payload.Signature
 

각각 Base64URL로 인코딩된 문자열이며, “.”으로 구분된다.

✔ 1. HEADER (헤더)

토큰의 메타데이터를 담는다.

예:

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

 

주요 필드:

alg 서명 알고리즘(HS256, RS256 등)
typ 타입—대부분 “JWT”

✔ 2. PAYLOAD (페이로드)

토큰의 실제 데이터가 들어있는 부분.
사용자 식별 정보, 권한, 만료 시간 등이 포함된다.

대표적인 claim:

sub 사용자 ID(Subject)
iss 발급자(Issuer)
aud 대상(Audience)
exp 만료 시간(Expiration)
iat 발급 시간(Issued At)
nbf 활성화 전 시간(Not Before)

커스텀 정보도 포함 가능:

{
  "user_id": "1234",
  "role": "admin",
  "tier": "premium"
}
payload는 “암호화가 아님”.
Base64URL 인코딩일 뿐이므로 누구나 내용을 확인할 수 있다.

 

✔ 3. SIGNATURE (서명)

Signature는 header + payload
서버가 가진 비밀키(secret) 를 사용해 만든 HMAC 또는 RSA 서명이다.

HS256(HMAC) 기준 공식:

HMAC_SHA256( secret, base64url(header) + "." + base64url(payload) )

 

RS256(RSA) 기준:

Signature = sign( private_key, header + "." + payload )
Signature는 payload 변조 여부를 검증 하는 역할이다.

 

2) Signature 생성 방식 (HMAC 기준)

JWT HMAC 구조는 복호화가 가능한 방식이 아니라,
서버가 “동일한 연산을 다시 해보고 결과가 같은지 비교하는 방식”으로 검증한다.

 

✔ 1) 클라이언트가 토큰을 보내면

HEADER.Payload.Signature

 

✔ 2) 서버는 자체 보유 secret으로 재계산

server_signature = HMAC(secret, header + "." + payload)

 

✔ 3) 두 값을 비교

if server_signature == client_signature:
    → 정상 토큰
else:
    → 변조된 토큰

 

📌 핵심:

  • 서버는 signature를 “복호화”하지 않는다.
  • signature만 보고 secret을 역추적할 수 없다(단방향).
  • 검증은 “재계산(compare)” 방식이다.

3) JWT가 위조 가능한 조건

JWT는 구조적으로 안전하지만, 다음 상황이면 100% 위조 가능하다.

공격자가 비밀키를 알고 있다면:

  • payload 조작
  • secret으로 HMAC 생성
  • 서버는 정상으로 판단
    → 관리자 토큰 생성 가능

즉, 비밀키 유출은 인증 체계 전체가 붕괴되는 상황이다.

 

4) JWT가 위험해지는 흔한 개발 실수

❌ 1) secret을 지나치게 짧게 설정

예: "1234"
→ brute-force로 signature 생성 가능

❌ 2) secret을 클라이언트 코드에 포함

JS, React 빌드 결과에 secret 포함된 사례 다수

❌ 3) 서버 환경변수 / .env 파일 유출

AWS S3 공개 버킷, GitHub 누출 등

❌ 4) alg: none 허용

전체 서명 기능을 무력화하는 유명 취약점

 

 

728x90