-
JWT (Json Web Token)보안/웹보안 2021. 3. 10. 20:57
JWT는 Json 을 이용해 안전하게 정보를 전달할 수 있는 웹 표준이다. 클라이언트가 서버에 인증을 요청할 때 사용된다.
인증을 위해 쿠키를 사용할 수도 있고 세션을 사용할 수도 있다.
그러나..
쿠키를 사용하면 클라이언트가 브라우저에 정보를 raw 하게 저장하기 때문에 보안에 취약하고
세션을 사용하면 서버가 여러대인 경우 모두 세션ID 를 가지고 있어야 인증이 가능하기 때문에 부담스럽다.
결론부터 얘기하면 JWT를 사용하면 클라이언트가 정보를 가지고 있으면서 위변조 또한 불가능하기 때문에 서버 입장에서 편리해진다.
왜 일까?
JWT의 구조
JWT의 구조를 보기전에 알아야 할 배경 지식은 JWT는 base64 인코딩과 해싱이 사용된다는 사실이다.
{Header} . {Payload} . {Signature}
Header, Payload, Signature가 '.'(dot) 을 기준으로 나누어져있다.
Header와 Playload 는 base64 인코딩 되어있다.
Header 에는 해싱 알고리즘과 토큰의 종류가 기재된다.
Payload 에는 주고받을 데이터가 입력된다. (base64 인코딩은 암호화가 아니므로 쉽게 디코딩된다. 중요한 정보를 입력하면 안된다.)
Signature 가 중요하다. Signature는 Header와 Payload 그리고 서버에서만 가지고 있는 Secret Key 가 합쳐져 해싱되어 있다.
★ 즉 Header와 Payload (데이터)의 값이 바뀌면 다시 해싱했을 때 이 Signature도 바뀐다는 것을 명심하자! ★
JWT를 통한 인증 과정
우선 이 과정은 로그인한 유저가 서버의 리소스를 취득할 권한이 있는지 확인하는 과정이다.
기본적인 프로세스는은 다음과 같다.
- 유저가 id/pw 를 입력하고 로그인 요청을 한다.
- 서버는 유저를 확인하고 JWT를 생성하여 유저에게 넘겨준다.
- 유저는 리퀘스트 헤더에 JWT를 포함하여 요청을 서버에게 보낸다.
- 서버는 요청을 받으면 JWT를 우선 확인하고 유효하다면 요청을 처리한다. (리소스를 제공한다)
여기서 궁금한 점은
- 왜 유저는 정보를 위/변조할 수 없을까?
- 서버는 어떻게 토큰이 유효한지 확인할까?
정답은 Signature에 있다.
위에서 언급했듯
Signature는 Header와 Payload 그리고 서버에서만 가지고 있는 Secret Key 가 합쳐져 해싱되어 있고
Header와 Payload (데이터)의 값이 바뀌면 다시 해싱했을 때 Signature도 바뀐다.
왜 위변조가 안되는지 예를 들어보자 (+ 서버의 토큰확인)
- 유저 Adam이 로그인 요청을 했다. (유저 이름 : Adam)
- 서버는 사용자가 로그인 가능함을 확인하고, {헤더}와 사용자정보 {Adam} 그리고 자기만 아는 Secret Key를 넣어서 해싱한다.
- 이게 바로 Signature 이다. (Signature 는 1234abcd 라고 하자.)
- JWT를 생성하여 유저에게 준다.
- JWT는 {인코딩된 헤더}.{인코딩된 Adam}.{1234abcd} 라고 하자.
- <유저의 조작시도 시작> 유저는 자신을 Bob 이라고 속이고 싶다. 그래서 Payload 에 있는 Adam을 Bob으로 슬쩍 바꿨다.
- 현재 유저가 가진 JWT는 {인코딩된 헤더}.{인코딩된 Bob}.{1234abcd} 가 되었다.
- 클라이언트가 해싱을 하진 않으므로 클라이언트가 가지고 있는 JWT에서 Signature는 그대로이다.
- 바꾼 JWT를 헤더에 담고, 무언가 서버에 요청한다. (나 Bob인데, 내 비밀번호 바꿔줘 등)
- 서버는 유저의 요청을 받았고, JWT를 확인해야한다.
- 유저가 보낸 JWT {인코딩된 헤더}.{인코딩된 Bob}.{1234abcd} 중에서 {인코딩된 헤더}.{인코딩된 Bob} 와 서버의 Secret Key 로 해싱했을 때 Signature인 {1234abcd} 가 나와야 한다.
- 그러나 해싱했을 때 {1234abcd}가 나오지 않는다.
- 왜냐하면 {1234abcd}는 Payload 데이터에 {인코딩된 Adam} 이 있을 때 나오는 해시값이기 때문이다.
- 이렇게 인증 실패.
유저는 해싱에 필요한 Secret Key도 모르므로 공격에 성공하는 Signature를 예상할 수도 없다.