개요 :
서명을 통해 위·변조를 감지하는 JWS 방식의 JWT 토큰을 썼다.
공부를 하다보니 Header와 Payload까지 암호화하는 JWE 방식도 있어서,
각 방식의 트레이드 오프를 공부하려고 한다.
JWS? 그리고 JWE?
JWS(서명)와 JWE(암호화)는 다른 방식으로 JWT를 구현하는 것을 말한다
서명과 암호화의 차이
서명(Signature) :
서명은 기본적으로 위·변조를 감지하는데 중점을 둔다.
서명은 데이터의 무결성과 출처를 검증하기 위한 것이다.
** 핵심은 데이터가 중간에 변조되지 않았음을 보장하는 것 **
암호화(Encrypt) :
암호화는 기본적으로 데이터의 기밀성을 보장하는데 중점을 둔다.
암호화는 데이터 자체를 보호하고 숨기기 위한 것이다.
** 핵심은 데이터 자체를 감추려는 것 **
JWS(JSON Web Signature)이란 ?
JWS는 서명(Signature) 방식을 택한 JWT 토큰을 의미한다.
JWS의 구성요소 3가지 :
Header : 서명 알고리즘과 토큰 유형을 명시한다
Payload : 데이터를 포함한다 (사용자 정보)
= Payload의 값은 Base64로 인코딩한다.
그러나, Payload가 암호화되지 않았기 때문에 보안적으로는사실상 평문이다!
Signature : 헤더와 페이로드를 합쳐 서명 알고리즘을 통해 생성한 서명의 값이다
이를 통해 데이터가 중간에 변조되지 않았는지를 확인할 수 있다.
JWS의 서명은 어떻게 위·변조를 감지할까 ? :
서버가 JWT의 [Header, Payload]를 서버가 가진 비밀키와 합쳐서 해싱 및 서명 처리
→ 서명을 생성한다.
만든 서명 값이 JWT의 서명 값과 불일치 시 데이터가 중간에 변조 됐음을 확인
IF 서버가 만든 서명 != JWT의 서명
→ 중간에 데이터가 변조 됐다는 것을 감지!
JWE(JSON Web Encrypt)
JWE는 데이터의 기밀성을 보장하기 위해 암호화 방식을 택한 JWT를 의미한다.
JWE의 구성 요소 5가지 :
{{header}}.{{encrypted-key}}.{{iv}}.{{ciphertext}}.{{tag}}
Header : 암호화 방식과 키 관리 방식을 명시한다
Encrypted Key : 토큰을 해독하는 데 필요한 키를 암호화 한 값
Initialization Vector (IV) : 암호화를 강화하기 위해 사용되는 초기화 벡터
Ciphertext : 암호화된 실제 데이터(JWE의 핵심)
Authentication Tag : 메시지 인증을 위한 태그(암호화된 데이터의 무결성을 검증)
JWE와 JWS의 차이
JWS(무결성) vs JWE(기밀성)
: JWS의 주 목적은 무결성이다.
중간에 위·변조 됐는지를 검증할 뿐, 토큰 내용이 공격자에게 노출되는 것을 막지않는다. JWS의 Payload는 사실상 평문이다
: JWE의 주된 목적은 기밀성이다.
→ 그렇지만, 무결성을 보장할 수도 있다 !
→ Authentication Tag의 검증을 통해서 !
→ 그러나 암호화된 데이터의 변조는 검증하지만, 출처(발신자)의 신뢰성은 확인하지 않는다.
정리
JWS는 Payload를 암호화 하지 않는다, 서명을 통해 중간에 데이터가 변경되지 않았음을 검증할 뿐이다.
JWE는 Ciphertext(Payload)를 암호화 한다. 데이터의 기밀성을 보장하고 싶을 때 사용하면 된다(민감한 정보를 전달할 때)
단, JWE는 구조가 JWS에 비해 복잡하고, 사용 시 비용이 크다는 점을 고려하여 무엇을 사용할지 결정해야 한다.
JWS를 JWE에 비해에 비해 많이 쓰는 이유가 무엇일까?
이유 : 대부분은 JWT 토큰에 사용자의 중요 정보를 넣어놓지 않기 때문에 JWT의 Payload가 공격자에게 들어가더라도 위험성이 적다고 생각하기 때문이다.
추가로 HTTPS에서 전송 구간 암호화가 이뤄지므로 추가 암호화가 필요하지 않은 상황이 많다. 즉, 기밀성이 중요하지 않은 경우에 JWE는 오버 엔지니어링이 될 수 있다.
JWS의 경우, 서버에서는 서명용 비밀 키만 관리하면 되지만, JWE의 경우에는 암호화 한 Payload를 복호화 하기 위해 비밀 키 혹은 공개/개인 키 쌍을 서버에서 관리해야 한다는 부담이 생긴다.
이는 분산 시스템에서 키를 여러 서버가 공유해야 해서 많은 부하가 있고, 키 유출 위험이 있다. 따라서 부가적으로 중앙화된 키 관리 시스템(KMS)을 필요로 한다.
단순하게 정리하면,
JWE는 기밀성이 중요하지 않다면, 오버 엔지니어링이 될 수 있다.
JWE는 구조가 복잡하고, 성능 오버헤드가 크다.
JWE는 암·복호화를 위한 키 쌍을 서버에서 관리해야 한다.
JWS의 Payload는 암호화 되지 않는다. 서명 방식은 위·변조만 검증하는 것이다.
JWS는 기밀성이 중요하거나, 중요 정보를 Payload에 담고 있는 경우 심각한 보안 위험이 존재