행복하자!!
343
2020-10-29 19:49:30 작성 2020-10-29 21:44:53 수정됨
6
799

JWT토큰 서명키는 개별적으로 생성해야 하지 않나요?


다른 블로그들 보니까 서명키가 전부다 고정으로 걸려있던데 토큰의 서명키는 클라이언트 별로 생성해야 하지 않나요?

토큰에서 유일하게 서명키가 식별자 역할을 하고 padding에 일부 바꿨다 해도 개별로 서명키가 있으니 해쉬떠서 확인하면 틀린걸 알거구요.

근데 왜 secretkey를 고정으로 했는지 이해가 안갑니다. 

0
  • 답변 6

  • RWB
    1k
    2020-10-29 20:23:05

    JWT 토큰 말씀하시는 건가요?

  • 행복하자!!
    343
    2020-10-29 21:11:33

  • RWB
    1k
    2020-10-29 22:05:49

    암호화된 JWT를 복호화하기 위해선 반드시 암호화할 때 사용했던 키를 사용하여 복호화해야합니다.

    대칭키의 경우 암호화에 사용했던 키로 복호화를 수행해야 하고,

    비대칭키의 경우 한쌍으로 생성된 공개키/개인키 중, 암호화에 사용했던 공개키의 다른 한 쌍인 개인키로 복호화를 수행해야 합니다.

    이 과정에서 각 클라이언트마다 암호화키를 다르게 줘버리면, 복호화 시 사용했던 키가 무엇인지 찾아서 해당 키를 이용해 복호화를 해야합니다.


    즉, 클라이언트마다 각각 다른 키를 이용해 암호화를 진행할 경우, 시스템이 사용했던 모든 키를 보유하고 있어야만 복호화가 가능합니다. 키 저장은 파일이나 DB 등 원하는 방식으로 저장하시면 됩니다. 사용자가 늘어나면 늘어날수록 관리해야할 키의 갯수가 증가합니다.

    JWT는 용도나 설계에 따라 일시적이기도 하므로 유저마다 한 개의 키가 아니라, JWT가 새로 생성되거나 삭제될 때마다 키를 관리, 삭제해야하는 번거로움이 생깁니다.


    이게 문제가 되는 이유가, 암호화된 JWT에선 어떠한 데이터도 얻을 수 없습니다.

    예를 들어, A의 JWT와 B의 JWT가 있고, 각각 P와 R의 대칭키로 암호화를 진행했다고 가정해봅시다.

    A의 JWT를 복호화하려면, 반드시 P 대칭키로 복호화를 수행해야 하는데, JWT만으로는 이 JWT의 소유자가 A인지, B인지 알 수 없기 때문에 일일히 복호화를 수행해서 확인해야 합니다.

    이 상황이 A와 B 뿐만 아니라, 수십, 수백명의 유저가 사용하게 된다면 JWT를 분석할 때마다 일일히 for문으로 비교분석을 진행해야 합니다. 즉, 총 유저가 많아질 수록 하나의 트랜잭션을 처리할 때 요구하는 리소스도 기하급수적으로 많아질겁니다.


    굳이 이런 구조로 구현하려면, DB에 JWT 토큰 문자열과, 사용했던 키를 각각 저장해서 관리하면 됩니다. 하지만 이런 구조를 구현하지 않는 이유는 다수의 키를 사용함으로써 확보되는 보안성보다 이런 구조를 운용하기 위한 소요비용이 월등히 크기 때문입니다.

    이 구조를 운용하실 경우, JWT는 로그인이나 특정 활동이 발생될 때마다 생성, 갱신, 삭제될 가능성이 많아 키의 생성, 삭제 또한 빈번히 일어나게 됩니다. 때문에 키를 분산해서 관리하는 것 또한 쉽지 않아 분산관리가 어렵습니다. 이런 환경이라면 키가 유출될 경우 한꺼번에 유출되기 때문에 키 하나를 운용하나 여러개를 운용하나 큰 차이는 없습니다.

    이와같은 구조가 보안적으로도 그렇게 뛰어나지 못한 이유기이도 합니다.

  • 행복하자!!
    343
    2020-10-29 22:22:07 작성 2020-10-29 22:23:39 수정됨

    늦은 시간에 답변 감사드립니다.

    답변을 읽어보니 키를 서버에 저장했을 경우 문제점에 대해서 애기해주셨는데 그것 보다 궁금했던 점은 JWT 토큰이 단방향 해쉬화를 통해 변조를 막는걸로 알고있는데 이때 사용되는 서명키가 모든 클라이언트마다 동일할 경우 padding값에 의해 달라지는데 이러면 위조가 너무 쉽지 않나 해서 질문드렸습니다.

    방금 생각난건데 padding에 보통 토큰 생성 시간을 넣기도 하나요? id만 넣으면 값만 바꾸면 위조되니까

    시간까지는 중복해서 로그인 하지 않는이상 동시에 생성될거 같지 않는데

  • RWB
    1k
    2020-10-29 23:23:58 작성 2020-10-29 23:24:27 수정됨

    제가 질문의 요지를 빗겨서 답변을 드린 것 같네요..


    답변을 읽어보니 키를 서버에 저장했을 경우 문제점에 대해서 애기해주셨는데 그것 보다 궁금했던 점은 JWT 토큰이 단방향 해쉬화를 통해 변조를 막는걸로 알고있는데 이때 사용되는 서명키가 모든 클라이언트마다 동일할 경우 padding값에 의해 달라지는데 이러면 위조가 너무 쉽지 않나 해서 질문드렸습니다.

    -> Padding이 JWT의 데이터 부분인 Payload 말씀하시는 것 같습니다. 동일한 키를 사용하시니, 내용에 가변적인 값이 들어가지 않고, 아이디별로 동일한 값이 들어간다면 생각하시는 문제가 발생하는 것이 맞습니다. 하지만 JWT를 탈취한다고 해도, 키를 모르면 소용이 없기 때문에 탈취한 JWT를 제한적으로나마 사용할 순 있어도 위변조나 분석은 키를 모르는 이상 어렵습니다.


    padding에 보통 토큰 생성 시간을 넣기도 하나요? 

    -> 네. 실제로 질문자분이 위에서 말씀해주신 걱정을 해소하기 위해 실제로 토큰의 생성시간을 기입하기도 합니다. 통상 iat라는 파라미터로 넣습니다. 가변데이터의 존재로 인해 나머지 주요 데이터가 동일하다 할지라도 다른 JWT 문자열이 생성됩니다. 전체 내용이 달라지니, 당연히 JWT 또한 달라지는 기본적인 원리입니다.


    저같은 경우 추가적으로 jid라는 파라미터에 임의의 UUID값 하나를 집어넣습니다. 이를 통해 JWT의 고유값을 확인할 수도 있지만, 그런 용도보다는 JWT의 고유값을 추가함으로써 가변데이터를 확보하는 목적입니다. 일종의 생산번호같은걸 추가하는거라 생각하시면 됩니다.


    임의의 JWT 고유값과 생성 시간 정도만 추가해도 질문자분의 우려는 충분히 해소할 수 있습니다.

  • 행복하자!!
    343
    2020-10-30 09:48:53

    답변 감사드립니다.

    혹시 시간되신다면 https://okky.kr/article/806717 이 질문도 봐주시면 감사하겠습니다.

    redirect관한 부분인데 클라이언트에서 redirect url을 받고 200까지 떳는데 새로고침이 안되서 질문을 올렸습니다.

  • 로그인을 하시면 답변을 등록할 수 있습니다.