JWT 는 어떻게 작동 하며, 토큰 을 안전하게 해독 하는 방법
JSON 웹 토큰의 구조, 서명 생성 및 검증 방법, 일반적인 주장, 보안 함정 및 JWT를 해독하는 방법을 이해하십시오.
· 4분 분량
JSON 웹 토큰 (JWT) 은 OAuth 및 OpenID Connect 로그인, API 게이트웨이, 마이크로 서비스 간의 단일 로그인 및 모바일 앱 세션 등 모든 곳에 있습니다. 그들은 또한 널리 오해되고 있습니다. 개발자들은 토큰을 해독하고, 읽기 쉬운 JSON을 보고 그것이 보안 문제인지 궁금해합니다. 다른 사람들은 암호화된 것으로 가정하여 민감한 데이터를 토큰에 저장합니다. 이 기사 는 JWT 가 무엇 이며, 어떻게 검증 될 것 이며, 위험 을 초래 하지 않고 어떻게 검사 할 수 있는지 정확히 설명 합니다.
JWT 의 세 가지 부분
JWT는 점으로 연결된 3개의 무작위 문자열과 같습니다.
eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJzdWIiOiI0MiIsImV4cCI6MTkwMDAwMDAwMH0.Kx8...
각 부분은 Base64URL로 코딩되어 있습니다.
- ** 헤더** 토큰 타입과 서명 알고리즘을 설명하는 JSON, 예를 들어
{"alg":"HS256","typ":"JWT"}. - ** 페이로드 ** JSON 포함 주장: 사용자와 토큰에 대한 진술, 예를 들어
{"sub":"42","exp":1900000000}. - 서명 비밀 또는 사설 키로 헤더와 페이로드에서 계산된 바이트.
Base64URL는 [Base64] (blog/base64-explained) 의 변종으로 +와 / 대신 -와 _를 사용하며 패딩을 떨어뜨립니다. 따라서 토큰은 URL 및 헤더에 탈출하지 않고 배치 될 수 있습니다.
중요한 것은 헤더와 유틸로드가 암호화된 것이 아니라 암호화된 것입니다. 토큰을 가진 사람이라면 누구나 읽을 수 있습니다. 토큰을 [JWT 디코더] ((/tools/jwt-decoder) 에 붙이면 배타적 부하가 즉시 나타납니다.
서명이 어떻게 작동하는지
JWT를 신뢰할 수 있게 만드는 건 그 서명입니다. 발급자는 암호화된 헤더와 페이로드를 가지고 점으로 연결하고 문자열에 서명합니다.
HS256 (HMAC와 SHA-256) 에서 발행자와 검증자는 비밀 키를 공유합니다.
signature = HMAC-SHA256(secret, base64url(header) + "." + base64url(payload))
RS256 또는 ES256를 사용하면 발행자가 개인 키로 서명하고 누구나 일치하는 공개 키로 확인할 수 있습니다. 종종 https://login.example.com/.well-known/jwks.json과 같은 JWKS 엔드포인트에서 공개됩니다. 많은 서비스가 토큰을 확인해야 하지만 오직 하나만이 토큰을 발행해야 할 때 비대칭 알고리즘이 선호됩니다.
서버가 토큰을 수신하면 서명 다시 계산하거나 확인합니다. 만약 의 단 한 문자가 변경되면 공격자가 "role":"user"를 "role":"admin"로 편집하면 의 서명이 더 이상 일치하지 않고 토큰이 거부됩니다.
당신이 알아야 할 등록 된 청구서
JWT 사양 (RFC 7519) 은 표준 주장 이름을 정의합니다:
iss(출제자): 토큰을 만든 사람, 예를 들어https://login.example.com.sub(주체): 토큰이 누구에 관한 것인지, 보통 사용자 ID입니다.aud(audience): 토큰이 누구에게 쓰여지는지, 예를 들어api.example.comexp(멸시): 토큰이 거부되어야 하는 시간, [유닉스 초] ((/blog/unix-timestamp-explained).nbf(not before): 토큰이 유효하지 않은 시간.iat(출제 시): 토큰이 생성되었을 때jti(JWT ID): 취소 목록에 유용한 고유 식별자.
신청은 자신의 주장을 추가합니다: scope, roles, tenant_id, email. 소수를 유지하십시오. 모든 요구는 모든 요청과 함께 여행합니다.
토큰을 올바르게 검증
서버는 이 순서대로 다음의 모든 것을 확인해야 합니다.
- 알고리즘은 당신이 기대하는 것입니다.
["RS256"]과 같은 허용 목록을 구성합니다. 토큰 헤더가 자유롭게 결정하도록 절대 허용하지 마십시오. 역사적 취약점은 공격자가none로 전환하거나 공개 키를 HMAC 비밀로 사용하도록 서버를 속일 수 있습니다. - ** 서명 유효하다**
kid이 당신의 신뢰할 수 있는 키 세트에서 선택한 올바른 키로 exp은 미래에 있고nbf는 과거에 있습니다, 30~60초의 작은 시계 편향을 허용합니다.- **
iss**는 귀하의 신원 제공자와 정확히 일치합니다. - **
aud는 ** 서비스의 식별자를 포함합니다. 그래서 다른 API에 발행된 토큰은 여러분의 API에 재생할 수 없습니다.
유지 관리 라이브러리 자바스크립트를 위해 jose, 파이썬을 위해 PyJWT, Go를 위해 golang-jwt를 사용하여 확인을 직접 작성하지 마십시오.
디코딩과 검증
디코딩은 첫 두 부분을 Base64URL로 디코딩하고 JSON을 분석하는 것을 의미합니다. 열쇠가 필요없고 진위도 증명되지 않습니다. 이 약은 다음과 같은 경우에 유용합니다.
- 왜 API가 401을 반환하는지 디버깅:
aud이 맞습니까? 토큰이 만료됐어? - 로그인 흐름이 실제로 어떤 범위나 역할을 부여하는지 확인합니다.
- 토큰 업데이트가 새로운
exp을 생성했다는 것을 확인합니다.
검증이란 위와 같이 서명과 주장을 확인하는 것을 의미합니다. 오직 서버만이 허가 결정을 내리고, 확인한 후에야 해야 합니다.
프론트엔드 코드는 사용자의 이름을 표시하거나 exp 이전에 갱신을 스케줄링하기 위해 토큰을 해독할 수 있지만 사용자가 브라우저에서 실행되는 모든 것을 수정할 수 있기 때문에 보안을 위해 해독된 주장에 절대 의존해서는 안됩니다.
브라우저에서 토큰을 저장하는 곳
완벽한 답은 없습니다.
- HttpOnly, Secure, SameSite 쿠키는 자바스크립트가 읽을 수 없습니다. 이는 크로스 사이트 스크립팅을 통해 토큰 도난으로부터 보호합니다. 그들은 CSRF 보호가 필요하지만 SameSite=Lax 또는 Strict는 대부분의 경우를 포함합니다.
- 메모리 (자바스크립트 변수) 는 지속성으로부터 안전하지만 재부하 시 손실됩니다. HttpOnly 쿠키에서 리프레시 토큰과 결합하십시오.
- localStorage는 편리하지만 페이지의 모든 스크립트에서 읽을 수 있습니다. 그래서 하나의 XSS 취약점은 모든 토큰을 누출합니다.
대부분의 웹 앱에서, 메모리에 있는 단기 접속 토큰과 HttpOnly 쿠키에 있는 갱신 토큰은 좋은 균형입니다.
만료 및 취소
JWT는 상태가 없습니다. 서버는 데이터베이스 검색 없이 확인할 수 있습니다. 다른 측면은 유효한 토큰이 만료되기 전에 쉽게 취소될 수 없다는 것입니다. 완화:
- 접근 토큰을 유지하기 짧습니다. 5~15분 정도가 일반적입니다.
- 새로운 액세스 토큰을 발급하기 위해 데이터베이스와 비교하여 안전하게 저장된 업데이트 토큰을 사용합니다.
- 고위험 행위의 경우
jti값의 취소 목록을 확인하거나 사용자별 "후 유효 토큰" 타임 스탬프를 확인합니다.
흔한 실수
- ** 비밀도 사용량에 넣습니다. ** 암호, API 키, 개인 데이터는 토큰을 가진 사람이라면 누구나 읽을 수 있습니다. 만약 비밀이 필요하다면 JWE를 사용하거나 서버 쪽에서 데이터를 보관하세요.
- 매우 오래 사용할 수 있는 토큰. 1년 동안 유효한 도킹은 1년 동안 침해됩니다.
- 청중 확인을 건너뛰는 것.
aud검증 없이, 낮은 특권 서비스의 토큰은 높은 특권 서비스에 대해 사용될 수 있습니다. - 약한 HMAC 비밀. HS256 비밀은 길고 무작위적이어야 합니다. 짧은 비밀은 단 하나의 토큰으로 오프라인으로 강제로 접근할 수 있습니다.
- ** 로깅 토큰.** 액세스 로그와 오류 추적기는 종종
Authorization헤더를 캡처합니다. 편집해
토큰을 안전하게 검사합니다.
디버깅을 할 때 브라우저에서 로컬로 실행되는 디코더를 사용하세요. 그래서 토큰이 제3자에게 보내지지 않습니다. 스크린샷을 공유하거나 티켓에 붙일 때 만료된 토큰이나 테스트 환경 토큰을 선호합니다. 체크:
- 헤더의
alg과kid는 공급자의 구성과 일치합니다. iss과aud는 여러분의 API가 기대하는 것과 일치합니다.exp,iat그리고nbf는 현재 시간에 비해 의미가 있습니다.- 범위와 역할은 작전이 요구하는 것을 포함합니다.
요약
JWT는 JSON 클레임의 서명된, 암호화되지 않은 팩입니다. 보안은 전적으로 서명을 확인하고 서버에서 클레임을 검증하는 것에서 나옵니다. 디코딩은 무해하고 디버깅에 유용합니다. 검증 없이 디코딩된 데이터를 신뢰하는 것은 진짜 위험입니다. 토큰의 유효기간을 단축하고, 용량도 작고 비밀도 없도록 하고, 알고리즘, 서명, 유효기간, 발행자 및 청중을 매번 검증하고, 토큰을 기계에 보관하는 도구로 검사하세요.
이 페이지는 영어에서 자동 번역되었습니다. 오류를 발견하시면 알려 주세요.