JWT를 사용하며 JWT에 대해 정리한 글입니다.
JWT(JSON WEB TOKEN)는 당사자 간에 정보를 JSON 객체로 안전하게 전송하기 위한 간결하고 독립적인 방법을 정의하는 개방형 표준입니다.
간단히 말해서 서로 다른 서비스 간에 발신자를 확인할 수 있는 민감한 정보가 포함된 json 형식의 암호화된 문자열입니다.
JWT는 헤더, 페이로드, 서명의 세 부분으로 구성됩니다. 각 부분은 토큰의 보안과 무결성을 보장하는 데 중요한 역할을 합니다.
따라서 JWT는 일반적으로 다음과 같은 모양을 취합니다.
xxxxx.yyyyy.zzzzz
헤더는 일반적으로 두 부분으로 구성됩니다. 토큰 유형(JWT)과 사용 중인 서명 알고리즘(예: HMAC SHA256 또는 RSA)이 그것입니다.
{
"alg": "HS256",
"typ": "JWT"
}
그런 다음 이 JSON은 Base64Url로 인코딩되어 JWT의 첫 번째 부분이 됩니다.
토큰의 두 번째 부분은 페이로드이며, 여기에는 클레임이 포함됩니다. 클레임은 엔티티(일반적으로 사용자)와 추가 데이터에 대한 표현입니다. 클레임에는 등록 클레임, 공개 클레임, 비공개 클레임의 세 가지 유형이 있습니다.
등록 클레임(Registered claims)
토큰에 대한 정보들을 담고있는 필수는 아니지만 권장되는 사전 정의된 클레임 세트입니다.
iss (Issuer) : JWT 발급자
발행한 주체를 식별합니다.
sub (Subject) : JWT의 주체(사용자)
aud (Audience) : JWT가 대상인 수신자
exp (Expiration Time) : JWT가 만료되는 시간
NumericDate 형식으로 되어있어야 하며 언제나 현재 시간보다 이후로 설정되어 있어야 합니다.
nbf (Not Before) : 처리를 위해 JWT를 수락해서는 안 되는 시간
NumericDate 형식으로 되어있어야 하며 클레임을 처리하려면 현재 시간과 같거나 이전 이어야 합니다.
iat (Issued At) : JWT가 발급된 시간으로, JWT의 연령을 결정하는 데 사용할 수 있습니다.
jti (JWT ID) : 고유 식별자, JWT가 반복되는 것을 방지하는 데 사용할 수 있습니다(토큰을 한 번만 사용할 수 있음).
공개 클레임(public claims)
이름 및 이메일과 같은 일반 정보를 포함할 수 있는 공개용 사용자 지정 클레임을 만들 수 있습니다. 공개 클레임을 생성하는 경우 등록하거나 네임스페이스를 통해 충돌 방지 이름을 사용해야 하며, 사용하는 네임스페이스를 통제할 수 있도록 적절한 예방 조치를 취해야 합니다.
비공개 클레임(Private claims)
비공개 사용자 지정 클레임을 만들어 애플리케이션과 관련된 정보를 공유할 수 있습니다. 예를 들어 공개 클레임에는 이름, 이메일과 같은 일반적인 정보가 포함될 수 있지만 비공개 클레임에는 직원 ID, 부서 이름과 같은 보다 구체적인 정보가 포함될 수 있습니다.
서명은 JWT 발신자가 실제 발신자인지 확인하고 메시지가 중간에 변경되지 않았는지 확인하는 데 사용됩니다.
서명을 생성하기 위해 Base64로 인코딩된 헤더와 페이로드를 비밀과 함께 가져와서 헤더에 지정된 알고리즘으로 서명합니다.
예를 들어 HMAC SHA256 알고리즘을 사용하여 토큰에 대한 서명을 만드는 경우 다음과 같이 하면 됩니다:
HMACSHA256(
base64UrlEncode(header) + "." +
base64UrlEncode(payload),
secret)
헤더와 페이로드 설정: JWT는 먼저 헤더(header)와 페이로드(payload)로 구성됩니다. 헤더는 토큰의 유형(JWT)과 사용된 서명 알고리즘을 명시합니다. 페이로드는 클레임(claim)이라고 불리는 정보 조각을 포함하며, 이는 사용자 식별 정보나 토큰에 대한 다른 데이터를 담을 수 있습니다.
서명 생성: 헤더와 페이로드는 각각 Base64로 인코딩되고, 이 둘을 합친 다음 서버의 비밀 키 또는 공개/개인 키 쌍을 사용하여 서명(sign)합니다. 이 서명 과정은 토큰이 중간에 변경되지 않았음을 보장하는 데 중요합니다.
이러한 과정을 통해 JWT는 웹 애플리케이션과 API에서 안전하고 효율적인 방법으로 사용자 인증 및 정보 교환을 가능하게 합니다. JWT의 구조와 이 두 가지 핵심 프로세스의 조합은 웹 보안에서 중요한 역할을 합니다.
단순 웹 토큰(SWT) 및 SAML 토큰과 비교할 때 JWT를 사용하면 여러 가지 이점이 있습니다.
더 컴팩트합니다: JSON은 XML보다 덜 장황하므로 인코딩할 때 JWT는 SAML 토큰보다 작습니다. 따라서 JWT는 HTML 및 HTTP 환경에서 전달하기에 좋은 선택입니다.
더 안전하게: JWT는 서명을 위해 X.509 인증서 형식의 공개/개인 키 쌍을 사용할 수 있습니다. 또한 JWT는 HMAC 알고리즘을 사용하여 공유 비밀로 대칭적으로 서명할 수도 있습니다. SAML 토큰은 JWT와 같은 공개/개인 키 쌍을 사용할 수 있지만, 모호한 보안 허점을 도입하지 않고 XML 디지털 서명을 사용하여 XML에 서명하는 것은 JSON에 서명하는 단순성에 비해 매우 어렵습니다.
더 일반적인: JSON 파서는 객체에 직접 매핑되기 때문에 대부분의 프로그래밍 언어에서 일반적입니다. 반대로 XML에는 자연스러운 문서와 객체 간 매핑이 없습니다. 따라서 SAML 어설션보다 JWT로 작업하기가 더 쉽습니다.
처리하기 쉽습니다: JWT는 인터넷 규모에서 사용됩니다. 즉, 사용자의 디바이스, 특히 모바일에서 처리하기가 더 쉽습니다.
JWT는 다양한 방법으로 사용할 수 있습니다:
인증: 사용자가 자격 증명을 사용하여 로그인에 성공하면 ID 토큰이 반환됩니다. OIDC(OpenID Connect) 사양에 따르면 ID 토큰은 항상 JWT입니다.
권한 부여: 사용자가 로그인에 성공하면 애플리케이션이 해당 사용자를 대신하여 경로, 서비스 또는 리소스(예: API)에 액세스하도록 요청할 수 있습니다. 이렇게 하려면 모든 요청에서 액세스 토큰을 전달해야 하며, 이 토큰은 JWT 형태일 수 있습니다. 싱글 사인온(SSO)은 형식의 오버헤드가 적고 여러 도메인에서 쉽게 사용할 수 있다는 점 때문에 JWT를 널리 사용합니다.
정보 교환: JWT는 서명이 가능하므로 발신자가 본인이 맞는지 확인할 수 있으므로 당사자 간에 정보를 안전하게 전송하는 좋은 방법입니다. 또한 JWT의 구조를 통해 콘텐츠가 변조되지 않았는지 확인할 수 있습니다.
JSON Web Token (JWT)은 웹 애플리케이션과 API에 널리 사용되고 있지만, 몇 가지 잠재적인 보안 취약점이 있습니다. 이러한 취약점을 이해하는 것은 JWT를 안전하게 사용하는 데 매우 중요합니다.
이러한 잠재적 취약점을 고려하여, JWT를 사용할 때는 안전한 알고리즘 선택, 키의 안전한 관리, XSS 공격 방지를 위한 적절한 저장 방법 선택, 토큰의 만료 및 재사용 관리, 그리고 데이터 전송의 보안을 강화하는 것이 중요합니다.
JWT (JSON Web Token) 관리의 모범 사례를 알고 있으면, 웹 애플리케이션과 API의 보안을 크게 향상시킬 수 있습니다. 여기에 안전한 JWT 사용을 위한 중요한 팁과 요령을 소개합니다.
JWT는 웹 기반의 인증과 권한 부여 과정에서 핵심적인 요소로 자리 잡았습니다. 이 토큰은 안전하고 효율적인 방법으로 사용자 신원을 확인하고, 서버와 클라이언트 간의 정보 교환을 쉽게 만듭니다. 특히, 단일 페이지 애플리케이션(SPA), 모바일 애플리케이션, 그리고 마이크로서비스 아키텍처에서 JWT의 중요성은 더욱 부각됩니다.
보안 측면에서, JWT는 사용자 인증 정보를 안전하게 전송할 수 있게 해주며, 이를 통해 사용자와 시스템 간의 신뢰를 구축합니다. 또한, JWT는 확장성이 뛰어나고 다양한 플랫폼과 언어에서 쉽게 구현할 수 있어, 현대의 다양한 웹 애플리케이션 개발 요구사항을 충족시킵니다.
하지만, 모든 기술과 마찬가지로, JWT도 적절히 관리되고 보안이 유지되어야 합니다. 잘못된 관리나 구현은 보안 취약점을 초래할 수 있으므로, JWT를 사용할 때는 모범 사례를 따르는 것이 중요합니다.
요약하자면, JWT는 웹 보안의 현재와 미래에서 중요한 역할을 하고 있습니다. 그것은 간편하고, 유연하며, 강력한 인증 수단으로서 웹 애플리케이션의 보안을 강화하는 데 필수적인 요소입니다