-
[Spring] JWT(Json Web Token)란? | 구조, 암호화 방법, 장단점Spring 2023. 6. 14. 18:04
JWT (Json Web Token)
: JWT(Json Web Token)란, JSON 포맷을 이용하여 사용자에 대한 속성을 저장하는 Claim 기반의 Web 토큰이다.
JWT는 필요한 정보를 자체적으로 지니는 Self-Contained 방식으로 정보를 안정성 있게 전달한다.
🔎 JWT의 구조
JWT는 Header, Payload, Signature 세 가지로 구성된다.
JSON으로 포맷된 각 부분은 Base64로 인코딩되어 표현되며, 각각의 구성 요소는 . 로 구분한다.
* Base64는 암호화 된 문자열을 반환하는 게 X
1️⃣ Header(헤더)
토큰의 헤더는 alg와 typ로 구성된다.
{ "alg": "HS256", "typ": "JWT" }
- alg: 해싱 알고리즘. 서명(Signature) 및 토큰 검증에 사용 (헤더를 암호화 하는 것이 아니고, 서명을 해싱하기 위한 알고리즘 지정)
- typ: 토큰의 타입
2️⃣ PayLoad(페이로드)
토큰의 페이로드에는 토큰에서 사용할 정보의 조각들인 클레임(Claim)이 담겨있다.
클레임은 등록된 클레임(Registered Claim), 공개 클레임(Public Claim), 비공개 클레임(Private Claim) 으로 나누어지며, key-value 형태로 존재한다.
- 등록된 클레임(Registered Claim)
등록된 클레임은 토큰 정보를 표현하기 위해 이미 정해진 종류의 데이터들로, 모두 선택적으로 작성이 가능하며 사용할 것을 권장한다.
- iss: 토큰 발급자(issuer)
- sub: 토큰 제목(subject), unique한 값을 사용한다. 주로 사용자 이메일 사용
- aud: 토큰 대상자(audience)
- exp: 토큰 만료 시간(expiration), NumericDate 형식으로 되어 있어야 함 ex) 1480849147370
- nbf: 토큰 활성 날짜(not before)
- iat: 토큰 발급 시간(issued at), 토큰 발급 이후의 경과 시간
- jti: JWT 토큰 식별자(JWT ID), 중복 방지를 위해 사용하며, 일회용 토큰(Access Token) 등에 사용
- 공개 클레임(Public Claim)
공개 클레임은 사용자 정의 클레임으로, 공개용 정보를 위해 사용된다. 충돌 방지를 위해 URI 포맷을 이용한다.
{ "https://suddiyo.tistory.com": true }
- 비공개 클레임(Private Claim)
비공개 클레임은 사용자 정의 클레임으로, 서버와 클라이언트 사이에 임의로 지정한 정보를 저장한다.
{ "access_token": access }
3️⃣ Signature(서명)
서명(Signature)은 토큰을 인코딩하거나 유효성 검증을 할 때 사용하는 고유한 암호화 코드이다.
서명은 헤더와 페이로드, 그리고 비밀 키를 기반으로 생성되며 해당 토큰이 변조되지 않았음을 확인하기 위한 메커니즘이다.
[ 서명 생성 과정 ]
1. 헤더(Header)와 페이로드(Payload)의 값을 각각 BASE64로 인코딩
2. 인코딩한 값을 비밀 키를 이용해 헤더(Header)에서 정의한 알고리즘으로 해싱
3. 해싱한 값을 다시 BASE64로 인코딩하여 생성
🔎 JWT 암호화 방법
JWT를 생성할 때 헤더와 페이로드 정보를 인코딩하고, 이들을 합친 문자열에 대해 비밀 키로 서명을 생성한다.
이때 대칭키(Symmetric Key) 또는 비대칭키(Asymmetric Key) 방식을 사용할 수 있다.
대칭키(Symmetric Key)
- 암호화 복호화 키가 같은 방식
- 같은 키를 사용해 암호화, 복호화를 수행하기 때문에 속도가 빠름
- 대표적으로 HMAC 암호화 알고리즘이 있음
- 값에 SHA-256을 적용해서 해싱 후 private key(== secret key, 대칭키 역할)로 암호화
- private key를 알고있는 서버만 Signature 유효성 검증이 가능(== JWT를 복호화 가능)
비대칭키(Asymmetric Key)
- 암호화 복호화 키가 다른 방식
- 다른 키를 사용해 암호화, 복호화를 수행하기 때문에 속도가 느리지만 그만큼 안전
- 대표적으로 RSA 암호화 알고리즘이 있음
- 마찬가지로 SHA-256 단방향 암호화 알고리즘과 함께 쓰임
- 값에 SHA-256를 적용해서 해싱후 private key(비밀키)로 암호화
- public key(공개키)는 공개적으로 제공. 어떠한 서버든 이 public key를 통해 JWT를 복호화 가능
🔎 JWT의 장점과 단점
👍🏻 장점
- auth0을 이용하면 아이디를 카카오, 네이버처럼 다른 사이트에서 이용할 수 있음
- 서버측 부하를 낮출 수 있고 독립적이기 때문에 능률적으로 접근 권한 관리를 할 수 있고 분산/클라우드 기반 인프라 스트럭처에 잘 대응할 수 있음
- 별도의 인증 저장소가 필요하지 않아서 인증서버와 db에 의존하지 않아도 됨
👎🏻 단점
- 서버로부터 받은 토큰이 쿠키 또는 로컬스토리지, 세션스토리지에 저장이 되므로 탈취당할 위험이 있으므로 token에 중요 정보를 넣지 않아야 함
- 토큰에 넣는 데이터가 많아질수록 토큰이 길어지는데 API를 호출할 때마다 토큰 데이터를 서버에 전달해야하므로 그만큼 네트워크 대역폭 낭비가 심할 수 있음
- 한번 발급된 token은 수정, 폐기가 불가 ➡︎ Access token, Refresh token 사용
📋 참고 자료
728x90'Spring' 카테고리의 다른 글
[Spring] Spring Security + JWT 로그인 구현하기 - 2 (17) 2023.06.15 [Spring] Spring Security + JWT 로그인 구현하기 - 1 (4) 2023.06.14 [Spring] 테스트 코드에서의 @Transactional 사용 (0) 2023.05.30 [Spring] 네이버 도서 검색 API 활용하기 (0) 2023.04.22 [Spring] Spring boot가 자동 등록하는 HandlerMapping과 HandlerAdapter (0) 2023.03.14