JWT에 대해 알아보자
by EarlyHail
JWT
JWT(Json Web Token)은 당사자 간에 정보를 JSON 객체로 안전하게(securely) 전송하기 위한 표준이다.
JWT를 이용하여 암호화 된 정보를 전송하는 용도로 사용할 수도 있지만 서명된 토큰(Signed tokens)
으로써 활용이 가능하다.
토큰에 서명을 하며 데이터를 전송하며 데이터의 무결성
을 보장할 수 있다.
JWT의 사용은 크게 2가지로 나뉜다.
-
Authorization
-
정보 교환
JavaScript에서 JWT 만들기
-
jsonwebtoken 패키지 설치
npm i jsonwebtoken
-
JavaScript로 토큰 encoding, decoding
const jwt = require("jsonwebtoken"); const SECRET = "ThisIsSecretKey"; const token = jwt.sign( { nickname: "EarlyHail", }, SECRET, { expiresIn: "1h", } ); console.log(token); // eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJuaWNrbmFtZSI6IkVhcmx5SGFpbCIsImlhdCI6MTYxMjUxNDQ2OCwiZXhwIjoxNjEyNTE4MDY4fQ.gbWjnO0lES0IZF4kHFri0wc5DjG2oukE-cjBPcfuEj64 const decodedToken = jwt.verify(token, SECRET); console.log(decodedToken); // { nickname: 'EarlyHail', iat: 1612514473, exp: 1612518073 }
Signed JWT의 구조
JWT의 구조를 알아보자.
위에서 만들어본 JWT를 자세히 보면 .
를 이용하여 총 3 부분으로 나뉘어 있는것을 확인할 수 있다.
-
Header
헤더는 일반적으로 두 부분으로 나뉘며, 토큰 유형 (JWT)와 Signature Algorithm의 정보가 들어가있다.
위 정보를 Base64Url로 인코딩한 정보를 삽입한다.
-
Payload
토큰화한 데이터가 들어가있다. 만들어진 시간, 만료 시간 등의 데이터가 추가로 들어갈 수 있다.
위 정보를 Base64Url로 인코딩한 정보를 삽입한다.
-
Signature
Header와 Payload를 각각 base64Url로 인코딩 한 값과 SECRET을 함께 서명 알고리즘을 적용한 결과값이 들어가있다.
JWT 홈페이지에서 Encoding, Decoding을 테스트해볼 수 있다.
민감한 정보를 JWT에 넣으면 안된다!!!
Signed token은 데이터 변조로부터 보호되는 무결성을 보장하지만 기밀성을 보장하지 못한다.
token1
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJuaWNrbmFtZSI6IkVhcmx5SGFpbCIsImlhdCI6MTYxMjUxOTk2MywiZXhwIjoxNjEyNTIzNTYzfQ.
akFIGyO0JUbJ2oJU3n2eM4UBku0Bk6mGsOJijpWDzEY
token2
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.
eyJuaWNrbmFtZSI6IkVhcmx5SGFpbCIsImlhdCI6MTYxMjUxOTk2MywiZXhwIjoxNjEyNTIzNTYzfQ.
sWJ2g0503AnN1pe8mGQT_BAqlXdfYFmxCo56fyuB4mg
두 개의 토큰은 서로 다른 SECRET으로 만들어진 토큰이다.
SECRET이 다르기 때문에 Signature를 제외한 Header, Payload의 값이 같은 것을 확인할 수 있다.
위 두 값은 Base64Url로 인코딩 되어있기 때문에 간단하게 해독할 수 있다. 따라서 기본 JWT 토큰에 저장되는 값 자체는 어떠한 보안적 처리도 되지 않은 상태
이다.
위 이유 때문에 토큰을 브라우저의 localStorage나 cookie에 저장하는 것을 지양해야 한다.
JWT가 탈취되면 어떤 상황이 일어날까
JWT가 탈취되면 어떤 상황이 일어날 수 있을지 생각해보자.
-
JWT에 담겨져 있는 데이터를 확인할 수 있다.
JWT의 Payload값을 알아낼 수 있다.
만약 JWT가 비밀번호 같은 민감한 정보를 포함한다면 큰 문제가 될 수 있다.
-
JWT 탈취자는 사용자 행세를 할 수 있다.
JWT를 이용하여 인증을 하는 서버의 토큰을 탈취한 사람은 해당 사용자인 것 처럼 권한을 가지고 접근할 수 있을 것이다.
따라서 토큰 자체를 숨겨야 하는건 당연하고 토큰의 유효기간을 짧게 설정하는 방법도 적용을 고려해보는게 좋을것 같다.
이 외에 생각해본 문제가 있다.
-
Payload를 Decode해서 사용자의 이름을 변경하고 제 3자의 권한을 가지고 서버에 접근할 수 있을까?
Payload에 “A” 유저 ID가 있을 때, 이를 “B” 유저 정보로 바꿔서 접근할 수 있을까?
답은
안된다
이다. Header와 Payload의 값을 서명 알고리즘인 HMAC(keyed-hash message authentication code, hash-based message authentication code)을 통해 Signature를 생성한다.인증을 위해 보내진 토큰의 Header, Payload는 무결섬 검증을 위해 복호화된 Signature 내의 Header, Payload와 비교되어 변경이 있다면 인증이 불가능하다.
Reference