JWT 토큰 암호화 알고리즘 - HS256과 RS256

땡글이·2023년 1월 15일
6

이 글에선 JWT 토큰의 전체적인 동작 방식에 대한 내용은 다루지 않고, 암호화 알고리즘에 대해서만 다루도록 하겠습니다. JWT 토큰 암호화 알고리즘 중 대표적인 HS256, RS256에 대해서만 다루겠습니다.

JWT 토큰의 전체적인 동작 방식은 'Session(세션)과 Token(토큰)의 차이는?' 포스팅을 참고해주시면 좋을 것 같습니다.
위의 포스팅에서는 대칭키 암호화 방식과 비대칭키 암호화 방식에 대해 다루고, 토큰의 구조 및 전체적인 동작 방식을 다루고 있습니다.

SHA 256 알고리즘

HS256, RS256 알고리즘에서 공통적으로 쓰이는 단어인 'S256' 이라는 단어는 SHA256 알고리즘을 의미합니다. 또한, SHA256 은 데이터 무결성을 위해 사용되는 암호화 해쉬 알고리즘(함수) 입니다.

SHA256 알고리즘은 SHA(Secure Hash Algorithm) 알고리즘의 한 종류로서 256비트로 구성되며 64자리 문자열을 반환합니다. SHA-256은 미국의 국립표준기술연구소(NIST; National Institute of Standards and Technology)에 의해 공표된 표준 해시 알고리즘인 SHA-2 계열 중 하나이며 블록체인에서 가장 많이 채택하여 사용하고 있습니다. 이름에 내포되어 있듯 2^256 만큼 경우의 수를 만들 수 있습니다. 개인용 컴퓨터로 무차별 대입을 수행해 해시 충돌 사례를 찾으려고 할 때 많은 시간이 소요될 정도로 큰 숫자이므로 충돌로부터 비교적 안전하다고 평가됩니다.

해쉬 알고리즘! 많이 들어봤지만, 자세히는... 자세히 알아보자!

Hash(해쉬) 알고리즘

해쉬는 임의의 크기를 가진 데이터를 고정된 데이터의 크기로 변환시키는 함수를 말합니다. 해쉬 알고리즘에는 SHA256 만 있는 것은 아니고, SHA512, SHA3 등 다양한 해쉬 알고리즘이 있습니다. 그러나 해쉬 알고리즘을 유용하게 사용하려면 총 5가지 요구조건이 있습니다.

단방향(One-Way)
해쉬 알고리즘은 복호화할 수 없습니다.

결정적(Deterministic)
만약 동일한 문서를 해쉬 알고리즘에 적용하면 똑같은 해쉬값을 얻어야 합니다.

연산이 빨라야 한다(Fast Computation)
해쉬 알고리즘을 잘 사용할 수 있을 만큼 연산 속도가 빨라야 합니다.

쇄도 효과(The Avalanche Effect)
쇄도 효과를 이미지로 나타내면, 눈사태 이미지를 예시로 들 수 있습니다. 쇄도 효과는 해쉬 알고리즘에서 매우 중요한 요건으로 쇄도 효과란 입력값이 아주 작은 변화만 있어도 해쉬값이 완전히 달라지는 것을 의미합니다. 쇄도 효과라고 불리는 이유는 알고리즘 구현 방식에 있습니다.

요점은 하나의 변화가 몇 가지의 추가적인 변화를 유발하고, 그 변화가 더 많은 변화를 유발하고 이는 더 많은 변화를 유발한다는 것입니다. 즉, 눈사태와 같다고 보면 될 것 같습니다.

충돌 저항성(Must withstand collisions)
해쉬값은 고정된 길이를 가집니다. 이는 매우 다양한 조합을 만들 수 있지만, 제한적인 것에는 변함이 없습니다. 예를 들어, 해쉬값이 64비트라고 한다면, 64자로 표현할 수 있는 다양한 조합이 나올 것입니다. 하지만, 디지털 데이터의 양은 너무 방대하기 때문에 64자로도 부족할 수 있습니다.

수학에서는 이러한 원리를 비둘기집 원리라고 합니다. 만약 10마리의 비둘기가 있고 집은 9개만 있다면 하나의 집에는 2마리의 비둘기가 들어가야 합니다. 즉, 슬롯의 개수가 부족하다면 충돌이 발생할 수 밖에 없습니다. 하지만 이런 일은 드물게 발생합니다. 가끔 그런 일이 벌어져도 아무런 영향이 없을 것입니다. 최종적으로 충돌 저항성 조건이 의미하는 바는 알고리즘이 인위적인 충돌에 견딜 수 있어야 한다는 뜻입니다.


다시 본론으로 돌아가서, SHA256 알고리즘에 대해 중요한 부분을 정리해보자면, SHA256 알고리즘은 "암호화 해쉬 알고리즘"에 속하고, "복호화가 불가능"하다는 특성을 가집니다. 이 내용을 토대로 이제 HS256, RS256에 대해 알아보도록 하겠습니다.

HS256 알고리즘

HS256 알고리즘은 JWT 토큰의 암호화 알고리즘으로 많이 쓰이는 암호화 알고리즘 입니다. 앞에서 HS256에서 S256은 SHA256 을 의미한다고 했습니다. H는 무엇일까요? HMAC 알고리즘을 의미합니다. HMAC 알고리즘은 대칭키 암호화 알고리즘입니다. 대칭키 암호화 알고리즘과 JWT 구조에 대해선, 'Session(세션)과 Token(토큰)의 차이는?' 포스팅 을 참고해주시면 되겠습니다.

HS256 = HMAC + SHA256

HS256 알고리즘을 이용한 JWT의 세부 동작 방식

  1. 서버에서 Header, Payload 는 Base64로 인코딩된다. (참고로, Base64 알고리즘은 복호화가 되는 알고리즘입니다)
  2. Signature 는 "Header + Payload + secret 값" 을 HS256 알고리즘으로 암호화됩니다.
  • _자세히 말하면, Base64 ( HS256 ( Base64(Header) + Base64(Payload) + secret key ) ) 가 됩니다.
  1. 생성된 Header, Payload, Signature 로 JWT 토큰을 만들어 클라이언트로 보내고, 클라이언트는 로컬 스토리지에 토큰을 저장합니다.
  2. 클라이언트는 서버에 요청이 있을 경우, 토큰과 요청 내용을 같이 보냅니다.
  3. 서버에서는 Header 와 Payload 를 Base64 알고리즘으로 복호화한 뒤, 서버만 알고 있는 개인키를 가지고 다시 HS256 알고리즘을 이용해 암호화해보고, 클라이어트에서 보낸 토큰과 같은지 유효성 검증을 합니다.
  • 만약 다르다면, 유효하지 않은 토큰!
  • 같다면, 유효한 토큰!

RS256 알고리즘

그리고, RS256에 대해 알아보겠습니다. RS256에서 R은 RSA 를 의미합니다. RSA 알고리즘은 비대칭키 암호화 알고리즘입니다. 비대칭키 암호화 알고리즘은 공개키(public key)와 개인키(private key)를 이용해 암호화를 진행합니다. 그리고 RS256 알고리즘은 HS256 과는 달리, secret 값이 따로 필요하지 않다.

RS256 = RSA + SHA256

RS256 알고리즘을 이용한 JWT의 세부 동작 방식

  1. 서버에서 Header, Payload 는 Base64로 인코딩된다. (참고로, Base64 알고리즘은 복호화가 되는 알고리즘입니다)
  2. Header, Payload는 서버의 개인키로 암호화 Signature 를 만듭니다.
  3. 그리고 토큰을 만들어 클라이언트에 보냅니다.
  4. 클라이언트는 서버에 요청을 보낼 때 토큰과 요청 내용을 같이 보냅니다.
  5. 서버에서는 토큰의 유효성 검증을 하기 위해서, 공개키로 Signature 를 복호화해봅니다.
  • 비대칭키 암호화 알고리즘 특징
    • 공개키로 암호화한 것은 개인키로 복호화 가능! ('데이터 암호화' 기능)
    • 개인키로 암호화한 것은 공개키로 복호화 가능! ('전자서명' 기능)

Reference

http://wiki.hash.kr/index.php/SHA256
https://namu.wiki/w/%ED%95%B4%EC%8B%9C
https://velog.io/@octo__/SHA256-%ED%95%B4%EC%8B%9CHash-%EC%9D%B4%ED%95%B4%ED%95%98%EA%B8%B0
https://community.auth0.com/t/rs256-vs-hs256-jwt-signing-algorithms/58609

profile
꾸벅 🙇‍♂️ 매일매일 한발씩 나아가자잇!

2개의 댓글

comment-user-thumbnail
2024년 1월 25일

감사합니다 좋은글 잘봤습니다

추가적으로 질문이 있는데 혹시 서버에서 암호화를 진행하였으니, 클라에서 로컬에 데이터를 저장하거나 할때 따로 암호화를 진행할 필요는 없을까요?

답글 달기
comment-user-thumbnail
2024년 6월 15일

JWT 암호화 방식에 대해서 잘 정리해 주셔서 도움이 되었습니다!

마지막에 전체적으로 Base64로 암호화하기도 합니다.

암호화가 아니라 인코딩이라고 하는 게 더 적절하지 않을까 싶습니다!

답글 달기