IT/기초 지식

JWT(JSON Web Token)란?

개발자 두더지 2024. 3. 10. 11:42
728x90

일본의 한 블로그 글을 번역한 포스트입니다. 오역 및 의역, 직역이 있을 수 있으며 틀린 내용은 지적해주시면 감사하겠습니다.

 

 

JWT란?


 JWT이란 Json Web Token의 약어로 정보를 안전히 송수신하기 위한 오픈 스탠드이다. 짧고 간단하게 JWT는 HTTP 헤더나 쿼리 스트링으로 확실히 정보를 보내거나, 받을 수 있게 된다. 주로 유저 인증이나 정보 교환을 위해 사용된다.

 JWT는 "헤더", "페이로드", "시그니처" 세 부분으로 구성되어 있으며, 각각 Base64Url로 엔코딩된다.

 

JWT의 필요성과 장점

 그럼 여기서 JWT가 필요한 이유와 어떤 장점이 있는지에 대해 알아보자. JWT의 최대 장점은 "상태를 유지하지 않는" 성질이다. 즉, JWT는 정보 자체를 토큰 내에 보유하고 있으므로 서버쪽에서 세션을 유지하고 있을 필요가 없다. 그로 인해, 토큰만 있으며 서버는 언제든 유저를 인증할 수 있으며, 그 덕분에 확장성과 퍼포먼스가 향상된다.

 더욱이 JWT는 가벼우므로 네크워크 상의 부담이 적어 리퀘스트를 횟수를 줄이는 것도 가능하다. 보안면에서도 HTTPS를 경유해서 안전하게 데이터 전송하는 것이 가능하므로 시그니처로 데이터가 조작 되지 않음을 확인할 수 있다.

 이러한 특징에 의해 JWT는 현대 웹 어플리케이션 개발에 매우 유용한 기술이라고 할 수 있다.

 

 

JWT의 기본 구조


 앞서 말했는 JWT는 주로 세 부분으로 구성되어 있다. 그건 "Header", "Payload", "Signature"이다. 지금 부터 설명할 각각의 특징과 역할, 그리고 JWT가 어떻게 작동하며 정보를 유지하는가를 이해하기 위해 이 세 부분에 대한 이해는 필수불가결이다.

 

JWT의 세 부분

 먼저 맨 처음 부분인 "Header"에 대해 이야기하도록 하겠다. Header는 JWT의 어떤 형식을 사용하여 토큰을 엔코딩할 것인지를 지정하는 부분이다. 일반적으로는 "JWT" 자체와 서명 혹은 암호화에 사용하는 알고리즘을 지정한다. 보통 "alg"이라는 속성으로 지정된다.

 다음은 "Payload"이다. Payload는 "화물"이라는 의미지만, 이 부분에는 JWT에 포함될 주요 정보, 즉 "Claims"가 저장된다. Claims는 다시 "등록이 끝난 Claims", "공개 Claims", "프라이베이트 Claims"로 나뉜다. 구체적으로 어떤 정보가 저장되는지에 대해서는 다음 세션에서 다루도록 하겠다.

 마지막으로 "Signature"은 JWT가 두 가지 주요한 안정성을 확보하기 위해 사용된다. 그 두 가지는 "정합성의 확인"과 "인증"이다. 시그니처는 헤더 데이터와 페이로드 데이터를 결합하여 비밀키 혹은 공개키를 사용해 해쉬를 생성한다.

 

각 부분의 목적과 역할

 각각의 목적과 역할에 대해서 구체적으로 살펴보자. 먼저 "Header"는 인증과 서명의 방법을 결정한다.  이 부분에서는 "alg"와 "typ"이라는 두 개의 필드가 포함되어 있다. "alg"필드는 JWT 서명에 사용할 알고리즘을 지정한다. 한편, "typ"필드는 토큰의 타입을 나타내는 것으로 이 경우는 "JWT"인 것을 표시한다.

 다음 "Payload"는 실제로 전하고 싶은 주요 정보를 저장한다. 특히 중요한 것은 "claim"이라고 부르는 유저의 속성과 역할, 유효 기간등의 정보가 저장된다.

 마지막으로 "Signature"는 헤더와 페이로드의 데이터가 변형되지 않았음을 확인하기 위해 사용된다. 시그니처가 올바를 경우에 한해 JWT가 조작으로 부터 보호되어 신뢰성이 확보되게 된다.

 이렇듯 각각의 부분이 연계되어 JWT그 본 목적을 달성한 안전한 인증이 가능하게 된다.

 

 

JWT의 사용법


 중요한 것은 JWT의 생성과 JWT의 검증 두 가지 프로세스이다. 이 두가지를 이해하면 인증과 인가를 포함해 다양한 JWT의 응용이 가능하게 된다.

 

JWT의 생성 : 라이브러리의 이용

 JWT는 여러 부분으로 이루어져 있는데, 그 생성은 각 프로그래밍 언어에 맞는 라이브러리를 활용하는 것으로 간단히 구현할 수 있다. "jsonwebtoken" (JavaScript용)나 "jwt-go"(Go언어용)등이 대표적이다.

 

JWT의 인증 방법

 다음은 생성한 JWT의 검증 방법에 대해서 살펴보자. 이 검증 프로세스는 주로 JWT를 받은 서버쪽에서 발생한다. 서버는 JWT가 정당한 것인지 확인하기 위해 포맷이 올바른지, 서명이 올바른지, 그리고 기한내인지를 검증한다.

 이 프로세스도 라이브러리를 이용하면 비교적 간단히 할 수 있다.

 

JWT의 사용예 : 인증과 인가

 JWT는 인증과 인가에 폭 넓게 활용할 수 있다. 인증에서는 유저가 누구인지를 확인하고 그 결과를 JWT로 엔코딩한다. 한편, 인가에서는 이 JWT를 디코드하여 그것을 바탕으로 유저가 리소스에 대해 적절한 액세스 권한을 가지고 있는지를 확정한다.

 또한 JWT는 클라이언트, 서버 간의 끊임없는 소통 속에서의 세션 관리에도 유효하게 활용된다. 웹 어플리케이션이나 모바일 어플리케이션에서의 로그인 세션 유지나, API 요구 마다 유저 식별하는 등에도 이용된다.

 이렇듯 JWT는 다양한 곳에서 활약하며, 미세 조정이나 커스터마이즈를 통해 요건에 맞게 솔루션으로서 기능한다.

 

 

JWT를 안전히 사용하기 좋은 방법


 여기에서는 JWT를 안전히 사용하기 위해 신경써야한 부분에 대해서 소개하고자 한다.

 

패스워드의 해시화

 패스워드의 해시화는 보안성 확보하기 위해 매우 중요한 방법 중 하나이다. JWT의 Signature부분은 Header와 Payload를 통해 계산되지만, 이 계산에 비밀키가 사용되어 일종의 패스워드가 된다. 이 패스워드(비밀키)다 다른 사람에게 알려지면, 위조된 토큰이 등록될 가능성이 있으므로 안전히 관리할 필요가 있다.

 패스워드의 해시화를 통해 비밀키를 안전히 관리하는 것이 가능하다. 해시화란 어떤 데이터에서 일정 길이의 값를 계산 산출하는 처리를 하는 것으로 원래의 데이터에서 해시값을 역산하는 것은 매우 어렵다. 이 특성을 활용하여 비밀키를 해시화하여 비밀키의 안전성을 높일 수 있다.

 

토큰 유효 기간 설정

 다음은 토큰의 유효기간 설정에 대해서 설명하도록 하겠다. JWT에는 유효기간을 설정할 수 있는 특징을 가지고 있다. 이 유효기간을 적절히 설정하는 것으로 혹시 토큰이 다른 사람에게 유출됐을 때 그 피해를 최소화 할 수 있다.

 유효기간을 넘긴 토큰근 인증에 실패하므로 부정이용될 수 없다. 또한, 토큰의 유효기간을 짧게 하는 것이 안전할 수 있지만, 유저가 빈번히 인증해야한다는 부담이 있으므로 어느 정도 기간을 두는 것이 좋다.

 

HTTPS상에서 토큰을 송신

 마지막으로 HTTPS상에서 코튼을 송신하는 것에 대해서 설명하도록 하겠다. HTTPS는 HTTP에 통신 내용을 암호화가 추가된 버전이다. 그러므로 통신경로상에서 데이터를 훔쳐 해독하는 것은 매우 힘들다.

 JWT는 인증 정보를 포함하므로 데이터가 도둑 맞으면 악용될 가능성이 있다. 그러므로 JWT를 송수신할 때에 항상 HTTPS를 사용할 것이 요구된다. 이로 인해, 통신 경로상에서의 데이터 유출 리스크를 줄일 수 있다.

 

 

JWT의 해석


JSON Web Token(JWT)은 도움이 되는 툴이지만 다루기 어렵기 때문에 올바른 해석방법을 익히는 것은 매우 중요하다.이번에는 토큰의 디코딩 방법과 '사칭' 공격 대책에 대해 소개하도록 하겠다.

 

토큰의 디코드 방법

 JWT는 Base64 Url 인코딩을 사용하여 정보를 Playload로 보유하고 있다.단, 이 정보는 암호화되어 있는 것은 아니고, 언제든지 디코딩할 수 있다.디코딩으로 온라인 JWT 디코더나 전용 라이브러리를 사용할 수 있다.

 단, 보안상의 이유로 디코딩한 정보를 신중하게 다룰 필요가 있다. 디코딩 자체는 간단하지만, 그 내용을 신뢰하는지 여부는 별개의 문제이다. 서명을 올바르게 검증함으로써 정보의 신빙성을 확인할 수 있다.

 

"위장" 공격 대책

 '위장' 공격은 불법 사용자가 정당한 사용자로 행동하는 것을 의미한다. JWT는 서명을 이용하여 정보의 신빙성을 보장하지만, 그러한 서명이 없는 JWT에는 주의해야한다.「none」알고리즘이 사용되었을 경우, 「위장」공격에의 가능성이 열리게 된다.

'none' 알고리즘을 방지하기 위한 방안으로 JWT 라이브러리를 구현한 시점에서 알고리즘을 지정해야한다. 알고리즘을 동적으로 분석하지 않음으로써 공격자가 알고리즘을 바꿀 수 있는 여지를 줄인다. 또한 강력한 서명 알고리즘을 사용하여 보안을 더욱 높일 수 있다. 자주 사용되는 것은 HS256이나 RS256 등의 알고리즘이다.

 어디까지나 JWT는 유용한 도구 중 하나이지만, 적절한 지식과 이해와 함께 사용해야 보다 안전하고 효율적인 시스템을 구축할 수 있다.

 

 

JWT의 응용


다중 인증을 이용한 사용

 최근에는 일부 사이트에서는 사용자의 안전성을 확보하기 위해 다중 인증(MFA)이 이용되고 있다. MFA는 사용자가 누구인지 확인하기 위해 여러 수단을 결합한 인증 방법으로 비밀번호 외에도 SMS 코드·바이오메트릭스(지문이나 얼굴 인식 등)·물리적 토큰(은행 키카드 등) 등을 사용한다.

 예를 들어, 사용자가 처음 로그인할 때 JWT는 일반 인증 정보와 함께 SMS로 전송된 임시 코드를 요구할 수 있다.이 코드가 맞을 경우 일시적인 JWT가 생성되어, 이후 요청에 대해 이 일시적인 JWT가 사용되도록 하는 것이다.

 다음 로그인 시 일시적 JWT가 다시 요청될 경우 사용자는 새로운 일시적 코드를 입력해야 한다.이를 통해 자신이 정말로 사용자임을 증명할 수 있다.

 

마이크로 서비스간의 정보 공유

마이크로 서비스 아키텍처는 대규모 애플리케이션을 분할하고 각 서비스가 독립적으로 동작함으로써 확대화, 갱신, 수정이 용이하다. 그러나 이들 서비스 간 인증과 인가는 어렵운데 JWT는 이 부분에서 도움이 될 수 있다.

 각 마이크로 서비스가 JWT를 가지고 있다면, 그것들은 보안을 유지하면서 다른 마이크로 서비스와 매끄럽게 통신할 수 있다. 예를 들어 하나의 마이크로서비스가 다른 마이크로서비스로 요청을 보낼 때 JWT는 헤더에 포함되며 받는 쪽의 마이크로서비스가 그 JWT를 검증함으로써 신뢰성 있는 요청임을 확인할 수 있다.

 또한 JWT는 클라이언트에서 서버 사이드로 전송됨으로써 상태를 유지하지 않고 인증 정보를 전송하는 것도 가능하다.이를 통해 스케일링과 폴트 톨러런스가 향상되고 시스템 전체의 보안과 신뢰성이 높아진다.

 

 

JWT의 한계와 주의점


 JWT(JSON Web Tokens) 기술은 간단성과 확장성 때문에 많은 브라우저 기반 애플리케이션에서 사용되고 있지만, 그 자체로 모든 과제를 해결하는 것은 아니며, 일부 제한과 주의점이 존재한다.

 

JWT의 오용에 의한 리스크

 잘못된 관리 또는 오용으로 인한 JWT의 위험은 높아질 수 있다. JWT는 클라이언트 측에서 저장되기 때문에 토큰이 도난당한 경우 공격자는 해당 토큰을 사용하여 사용자를 모방할 수 있으며, 이는 심각한 보안상의 문제가 된다.

 게다가 JWT는 일단 발행되면 유효기간까지 비활성화할 수 없다. 이는 만일 토큰이 도난당한 경우 등의 긴급 상황에 대응하기 어렵다는 것을 의미한다.

 또한 적절한 암호화 방식을 사용하지 않는 경우도 문제가 발생할 수 있다. JWT는 취약한 알고리즘을 사용하여 서명될 수 있는데, 이 경우 공격자에 의해 서명이 조작될 수 있다.

 

JWT와 세션 비교 : 각각의 장점과 단점

 JWT와 세션은 각각 다른 목적과 요건을 가지고 있다. JWT에서는 사용자의 정보가 토큰 자체에 저장되기 때문에 상태를 유지할 필요가 없다는 장점이 있다. 이를 통해 서버의 리소스를 절약할 수 있다. 게다가 크로스 오리진 인증이 쉬워진다는 점도 장점이라고 할 수 있다. 한편, 위에서 언급한 바와 같이 JWT는 한번 발행되면 유효기간까지 무효화하기 어려워 보안상의 우려를 야기할 수 있다.

 그러한 단점에 대해 세션을 사용하면 서버 측에서 세션을 관리하고 필요에 따라 세션을 비활성화할 수 있다. 그러나 세션은 상태를 유지할 필요가 있으며, 대량의 사용자를 취급할 때는 서버 리소스를 대량으로 소비할 가능성이 있다. 또한 세션 정보는 크로스 오리진에서 공유되지 않기 때문에 마이크로 서비스 아키텍처 등의 환경에서는 JWT가 적합하다.


참고자료

https://www.netattest.com/jwt-2023_mkt_tst

728x90