암호화된 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는 로그인이나 특정 활동이 발생될 때마다 생성, 갱신, 삭제될 가능성이 많아 키의 생성, 삭제 또한 빈번히 일어나게 됩니다. 때문에 키를 분산해서 관리하는 것 또한 쉽지 않아 분산관리가 어렵습니다. 이런 환경이라면 키가 유출될 경우 한꺼번에 유출되기 때문에 키 하나를 운용하나 여러개를 운용하나 큰 차이는 없습니다.
이와같은 구조가 보안적으로도 그렇게 뛰어나지 못한 이유기이도 합니다.