브렌쏭의 Veritas_Garage

중간자 공격으로 부터의 탈출 : JWT 본문

[Project_만들다]/[Project_자아내다]

중간자 공격으로 부터의 탈출 : JWT

브렌쏭 2022. 4. 2. 19:23

https://jwt.io/

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties

보안을 위한 여러 방법 중, JSON Web Token 이라는 것이 있다. 공개 표준 암호화 기법중 하나인 모양인데, 가벼우면서도 효과적인 방식이라고 소개하고 있다. Digital sign을 이용하고, 공개키 암호화와 비밀키 암호화를 전부 지원하고 있다.

Signed tokens can verify the integrity of the claims contained within it,
while encrypted tokens hide those claims from other parties

서명된 토큰은 통신 요청의 진실성을 증명하고, 동시에 암호화된 토큰은 통신요청 자체를 다른 사람들로 부터 안전하게 분리시켜준다. 

요는 이 모든 것이 중간자 공격을 막기 위한 방편이라는 점이다

굳이 JWT를 이용해야 하는 장점이 뭘까

인증과 정보교환의 경우, JWT가 강점을 가진다.

  • Authorization: This is the most common scenario for using JWT. Once the user is logged in, each subsequent request will include the JWT, allowing the user to access routes, services, and resources that are permitted with that token. Single Sign On is a feature that widely uses JWT nowadays, because of its small overhead and its ability to be easily used across different domains.

 

  • Information Exchange: JSON Web Tokens are a good way of securely transmitting information between parties. Because JWTs can be signed—for example, using public/private key pairs—you can be sure the senders are who they say they are. Additionally, as the signature is calculated using the header and the payload, you can also verify that the content hasn't been tampered with.

 먼저 인증의 경우, 유저가 로그인을 하면서 JWT를 포함한 로그인 요청을 보내게 된다. 올바른 토큰을 제공함으로 그 토큰에게 허용된 권한의 기능을 지정해서 풀어줄 수 있다. SSO 같은 요즘은 흔한 로그인 방식도, JWT를 이용하면 오버헤드를 줄이고 여러 다른 도메인에 걸쳐 적용되도록 할 수 있다.

 정보교환에서도 강점이 있다. 공개키/개인키 방식을 이용한다면, 정보를 정확하게 요청하는 주체가 누구인지 알 수 있게 된다. 정보를 가로채이거나, 정보를 받으려는 사람으로 가장한 탈취를 피할 수 있다. 동시에, 서명이 헤더와 용량를 계산해서 산출 되므로, 그 정보의 내용이 손실되거나 오염되지 않았음을 보장할 수 있게 된다.

JWT의 구조

  • header 헤더
  • payload 용량
  • signature 서명

3 가지의 요소로 되어있다. 따라서 다음과 같은 형태를 가진다. 

xxxxx.yyyyy.zzzzz

 

Header

The header typically consists of two parts: the type of the token, which is JWT,
and the signing algorithm being used, such as HMAC SHA256 or RSA.

든든하다. 라기 보단 일단 못믿을 구석이 없다. 별게 없는데다가 암호화 방식도 유명한 방식 중 하나니까. 그리고 JSON이 Base64Url 로 암호화되어 위에서 첫 xxxx. 부분을 채우게 된다.

{
  "alg": "HS256",
  "typ": "JWT"
}

암호화 전의 형태는 이렇게 생겼다.

Payload

payload, which contains the claims. Claims are statements about an entity (typically, the user) and additional data

페이로드는 요청을 저장하는 곳이다. 요청은 데이터 엔티티에 대한 선언과 추가 데이터 등등이 포함된다. 페이로드는 3가지로 나뉜다.

{
  "sub": "1234567890",
  "name": "John Doe",
  "admin": true
}

내용물은 이렇고 마찬가지로 Base64Url 로 변환되어 yyyy 부분으로 들어가게 된다.

Do note that for signed tokens this information, though protected against tampering, is readable by anyone. Do not put secret information in the payload or header elements of a JWT unless it is encrypted.

서명된 토큰의 경우, 이 정보가 템퍼링에 대비해 보호되긴 하지만, 누구나 읽을 수 있다는 것을 명심해야 한다. 따라서 이 위치에 비밀정보를 넣어놓으면 의미가 없다. 정보가 암호화 되어 특정 대상만 볼수있게 하려면 반드시 암호화를 해야한다.

Signature

서명을 생성하기 위해서는 헤더부분을 인코딩해야한다. 서명은 다음과 같은 방식으로 만들어진다.

HMACSHA256(
  base64UrlEncode(header) + "." +
  base64UrlEncode(payload),
  secret)

서명은 메세지가 이동하는 도중 변조되지 않았음을 증빙한다. 더 나아가 개인키로 서명된 토큰이라면, 누가 보낸 것인지 발송자 또한 JWT를 통해  증빙가능하다.

합체

헤더, 페이로드, 서명을 모두 모아 Base64Url 형식으로 변환한 뒤 이어붙이면 JWT의 완성이다. 따라서 HTML이나 HTTP 방식을 통해 쉽게 주고 받을 수 있으며 XML기반인 SAML에 비해 보다 가벼운 용량으로 작동한다. 모든 과정을 거친 JWT는 다음과 같이 보인다.

딱 봐도 암호암호스럽게 생겼따

연습하기

https://jwt.io/#debugger-io

 

JWT.IO

JSON Web Tokens are an open, industry standard RFC 7519 method for representing claims securely between two parties.

jwt.io

이 곳에서 연습을 하고 해독을 할 수 있다. 물론 JWT의 생성이나 인증 또한 가능하므로 익숙해지도록 하자.

주의사항

In authentication, when the user successfully logs in using their credentials, a JSON Web Token will be returned. Since tokens are credentials, great care must be taken to prevent security issues. In general, you should not keep tokens longer than required

민감한 개인정보와 같은 것들도 세션에 넣어 보관하지 않도록 주의하자.

JWT를 HTTP헤더에 담아 보낼 경우, 지나치게 커지지 않도록 해야한다. 어떤 서버들은 8KB가 넘는 크기의 헤더를 받아들일 수 없게 되어있기도 하기 때문이다. 하여간 뭐든간에 JWT로 구겨넣어서 보내려고 하면, 차라리 다른 방법을 쓰는 것이 나을 수도 있다.

 Auth0 Fine-Grained Authorization

If the token is sent in the Authorization header,
Cross-Origin Resource Sharing (CORS) won't be an issue as it doesn't use cookies.

API를 제공할 서버와 그것을 인증해주는 것은 제3자 입장의 Auth0 에서 담당하게 된다.

결론

어쨋든 XML기반의 암호화된 SAML보다는 훨씬 진보된 것이라는 점이고, 그 크기의 가벼움도 비할 바가 아니므로 JWT를 쓰면 되겠다.

위가 JWT, 상당히 짧고 간결하다

'[Project_만들다] > [Project_자아내다]' 카테고리의 다른 글

문맥이 너무해  (0) 2022.04.07
Storage : 쿠키, 세션 & 로컬  (0) 2022.04.07
로그인, 그 참을 수 있는 무거움  (0) 2022.04.05
ERD : 관계형 DB  (0) 2022.03.31
code first & schema first  (0) 2022.03.30
데이터베이스 스키마  (0) 2022.03.30
OOP*( NestJS + TypeORM ) = [ DTO & Entity ]  (0) 2022.03.30
Comments