본문 바로가기

Back-End

헷갈려서 남기는 JWT 서명

반응형

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에 맞는 서명을 만들 수가 없어요.

반응형