JWT (JsonWebToken) 의 원리

1

 

JWT (JsonWebToken) 의 원리

REST에는 표준이 딱히 존재하는 것은 아니지만, 보통 REST는 Stateless를 지향하기 때문에 쿠키나 세션방식을 사용하지 않는다고 한다. 사실 세션은 보통 서버의 메모리에 저장되기 때문에 많은 세션이 생성되면 서버쪽에서도 부담스러운것이 사실이다. 그래서 OAuthAPI Token 등의 방식을 사용하는데, API Token에서 JSON을 사용하는 JWT라는 방식이 존재한다.

JWT는 JsonWebToken의 준말으로써 Claim 기반이라는 방식을 사용한다고 한다. Claim 방식이란 Token 문자열 그 자체에 정보를 가지고 있다는 뜻이다. JWT는 이 Claim을 JSON을 사용하여 저장한다.
[code javascript]
{
“id” : “l0gic”,
“name” : “Chodonghyun”
}
[/code]
이렇게 모든 정보가 Token안에 존재하니 서비스 제공자 입장에서는 따로 데이터를 가져올 필요가 없다는 것이 장점이다.

JWT의 원리

Payload

JSON은 기본적으로 \n 등의 개행문자를 가지고 있어 URL에 그대로 넣기에 불편하다. 그렇기 때문에 BASE64 인코딩을 하여 저장한다. 위에서 예를 든 Claim JSON을 BASE64로 인코딩을 하면 다음 문자열이 나온다.

ew0KCSJpZCIgOiAibDBnaWMiLCANCgkibmFtZSIgOiAiQ2hvZG9uZ2h5dW4iDQp9

이 문자열을 Payload 라고 한다.

Signature

하지만, 하나 불안한 점이 있다. BASE64로 인코딩된 문자열은 간단하게 복호화가 가능하다. 누군가가 이 문자열을 복호화 하여 정보를 변조하게 되면 큰 문제가 발생할 수 있다. 이 메세지가 변조되지 않았음을 증명하는 것을 무결성(Integrity)이라고 한다.

이 무결성을 보장하는 방법으로 JWT는 HMAC 이라는 방식을 사용한다. HMAC이란 The Keyed-Hash Message Authentication Code 의 준말이다. Hash화 된 키를 사용하여 메세지의 무결성을 검증하는 방법이다. HMAC값은 Claim값을 특정하게 설정된 비밀키를 이용해 암호화 되기 때문에 개발자가 설정한 비밀키를 모르는 이상 HMAC값을 생성하거나 복호화 할 수 없게 되고, 그렇게 되면 Claim 값이 변경되어도 쉽게 변조 여부를 알 수 있다.

5b78c2352155780e4438d8ac9b121803ac10bf0dd85f92878a92d0721fd91234

위의 Claim값을 SECRET_KEY 라는 비밀키로 SHA-256 해쉬 알고리즘을 이용해 암호화 한 값이다.

이 문자열을 Signature 라고 한다.

0797ace6e80f331ba099aae50657fe4d21c9f55417a3a6cc5bfd742f7700b818

비밀키를 SECRET__KEY로 설정하여 암호화 한 값이다. 한글자 추가된 것 뿐인데, 모든 문자열이 완벽하게 바뀌었다.

Header

하지만, 해쉬 알고리즘은 SHA-256 만 있는 것은 아니다. 어떤 알고리즘으로 암호화 되어있는지 명시해놓지 않으면, 우리는 복호화를 하여 정보를 얻을 수 없다. 그래서 우리는 JSON의 형태로 어떤 알고리즘으로 암호화를 했는지 알려주어야 한다.
[code javascript]
{
“alg”: “HS256”,
“typ”: “JWT”
}
[/code]
이 문자열을 Claim 을 인코딩 한 것 처럼 BASE64로 다시 암호화 해준다.

ew0KCSJhbGciOiAiSFMyNTYiLA0KCSJ0eXAiOiAiSldUIg0KfQ==

이것을 우리는 Header 라고 한다.

Token

JWT 토큰은 [Header].[Payload].[Signature] 의 형식으로 구성되어 있다. 각 항목마다 . 으로 구분되어 있는 모습을 볼 수 있다.

위에서 생성한 Header, Payload, Signature 을 저 형식으로 붙여 만들어보자.

ew0KCSJhbGciOiAiSFMyNTYiLA0KCSJ0eXAiOiAiSldUIg0KfQ==.ew0KCSJpZCIgOiAibDBnaWMiLCAN
CgkibmFtZSIgOiAiQ2hvZG9uZ2h5dW4iDQp9.0797ace6e80f331ba099aae50657fe4d21c9f55417a3
a6cc5bfd742f7700b818

(줄바꿈이 자동으로 안되서 임의로 개행을 한 것이다.)

이렇게 무결성이 보장되고, Token 그 자체에 사용자의 정보가 포함된 JWT 값이 생성되었다!