반응형
JWT는 .으로 구분된 3파트로 이루어져 있어요.
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1dWlkLTEyMyJ9.X2vMTMaGvVrFoGMGmCWBJvTpFE4Wnj8LkBdPqRs1234
─────────────────────.──────────────────────────.────────────────────────────────────────────
Header Payload Signature
서명이 만들어지는 과정:
1. Header 인코딩
{ "alg": "HS256" }
→ Base64 → eyJhbGciOiJIUzI1NiJ9
2. Payload 인코딩
{ "sub": "uuid-123", "nickname": "Roy" }
→ Base64 → eyJzdWIiOiJ1dWlkLTEyMyJ9
3. 서명 생성 ← JWT_SECRET 여기서 사용
HMAC_SHA256(
"eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1dWlkLTEyMyJ9",
JWT_SECRET
)
→ X2vMTMaGvVrFoGMGmCWBJvTpFE4Wnj8LkBdPqRs1234
4. 합치기
Header.Payload.Signature
검증할 때:
받은 토큰:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1dWlkLTEyMyJ9.X2vMTMaGvVrFoGMGmCWBJvTpFE4Wnj8LkBdPqRs1234
서버가 하는 일:
① Header.Payload 부분만 꺼냄
② JWT_SECRET으로 서명 다시 계산
HMAC_SHA256("eyJhbG....eyJzdW...", JWT_SECRET)
→ X2vMTMaGvVrFoGMGmCWBJvTpFE4Wnj8LkBdPqRs1234
③ 비교
계산한 값 == 토큰의 3번째 파트?
일치 → 통과
불일치 → 거부
해커가 Payload 바꾸면:
조작된 토큰:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1dWlkLTk5OSJ9.X2vMTMaGvVrFoGMGmCWBJvTpFE4Wnj8LkBdPqRs1234
─────────────────────────── ← uuid-999로 바꿈
← 근데 서명은 그대로
서버:
eyJhbGciOiJIUzI1NiJ9.eyJzdWIiOiJ1dWlkLTk5OSJ9 로 서명 계산
→ ZpQ9xR2mK... (완전히 다른 값)
ZpQ9xR2mK... ≠ X2vMTMaG... → 거부
Payload가 1글자라도 바뀌면 서명값이 완전히 달라지거든요.
JWT_SECRET 없이는 바뀐 Payload에 맞는 서명을 만들 수가 없어요.
반응형
'Back-End' 카테고리의 다른 글
| tmux 완전 정복 — 개발자를 위한 명령어 치트시트 (0) | 2026.06.14 |
|---|---|
| # Java 개발자를 위한 Python 문법 정리 (0) | 2026.05.23 |
| SSHJ란 무엇인가 (0) | 2026.03.19 |
| AES-256-GCM 암호화 방식 정리 (0) | 2026.03.17 |
| 금융기관 API에서 사용하는 Signed JWT + RFC8785 메시지 서명 구조 정리 (0) | 2026.02.25 |