대칭키는 마치 우리가 어렸을 때 사용했던 집 열쇠 하나만으로 집 문을 잠그거나 열 수 있었던 것 처럼, 대칭키 하나로 정보를 암호화 및 복호화할 수 있다.
이를 이용해 https 통신에서는 통신하는 양 측 서버에서 같은 대칭키를 가지고 서로 주고받는 데이터를 암호화, 복호화하며 안전하게 통신한다.
통신 중 중간자 공격이 발생하여 정보가 탈취당하더라도 대칭키를 모르는 중간자는 정보를 해독할 수 없기 때문에, 대칭키가 외부로 노출되지 않는 이상 기밀성이 유지된다.
그러면 두 서버 간 정보를 주고받기 이전, 대칭키를 어떻게 공유할까?
비대칭키는 두 개의 key로 구성된다.
두 개의 키 중 하나는 외부로 공개되고 나머지 하나는 server만 알고 있는다. 이를 각각 공개키, 비공개키라 한다.
비대칭키를 통해 정보를 주고받는 방식은 다음과 같다.
1. 공개키를 이용해 정보를 암호화
2. 정보 전송
3. 정보를 제공받는 server에서는 비공개키를 이용해 정보를 복호화한다.
공개키를 통해 정보를 암호화하고, 비공개키를 통해 복호화한다.
즉, 누구나 공개키를 통해 정보를 암호화할 수는 있지만 한 번 암호화된 정보는 비공개키를 알고 있는 server 외 어느 누구도 복호화할 수 없다. (심지어 정보를 암호화한 client 마저도)
이와 같은 원리를 이용하여 양 측 서버는 대칭키를 주고받을 수 있다.
1. 공개키를 이용해 대칭키를 암호화
2. 대칭키 전송
3. 정보를 제공받는 server에서는 비공개키를 이용해 대칭키를 복호화한다.
4. 양측 서버는 서로 같은 대칭키를 가지고 있는 상태가 되므로, 이후의 통신에서는 모든 정보를 대칭키를 통해 암호화 및 복호화한다.
이해하기 쉽게, 우리가 흔하게 사용하는 웹 서비스와 client 간 통신하는 흐름을 살펴보자.
Google과 같은 웹 서버는 https 통신을 통해 client 와의 통신을 모두 암호화한다.
그 말인 즉, password와 같은 민감정보는 통신 중간 외부인이 개입하더라도 정보가 암호화되어 있기 때문에 해당 정보의 보안성이 유지된다는 것인데
위에서 말한 것과 같이 정보를 암호화하기 위해서는 google 서버와 client 서버가 같은 대칭키를 가지고 있어야 한다. 그리고 대칭키를 교환하는 과정은 다음과 같다.
1. client 가 google 에 통신하기 위해 handshake하는 과정 중 (대칭키 공유 과정)
1) client는 google에서 제공하는 공개키를 통해 임의로 생성한 대칭키를 암호화한다.
2) 암호화한 대칭키를 google에 전송한다.
3) google server는 자신만 알고 있는 비공개키를 통해 암호화된 대칭키를 복호화하여 사용자 별로 저장한다.
2. 데이터 송 수신 간
1) google과 client는 같은 대칭키를 가지고 있는 상태이다.
2) client는 google에 전송하는 정보를 대칭키를 통해 암호화한다.
3) google은 client로부터 넘겨받은 정보를, client가 제공한 대칭키를 통해 복호화한다.
굳이 대칭키를 사용해야 하는 이유가 뭘까?
위와 같은 흐름이라면, 굳이 handshake 간 대칭키를 공유하지 않아도 정보를 주고받는 통신에서는
1. 공개키를 이용해 정보를 암호화
2. 정보 전송
3. 정보를 제공받는 server에서는 비공개키를 이용해 정보를 복호화한다.
의 방식만으로도 민감정보를 보호하며 서버와 통신할 수 있다.
그럼에도 대칭키를 굳이 공유하여 보안에 활용하는 이유에는 두 가지가 있는데,
첫 번째는
비대칭키를 이용하여 암호화 및 복호화하는 과정에 비용이 많이 발생하기 때문이다. 비대칭키를 이용하는 연산은 대칭키를 이용하는 것보다 실제 연산이 많이 들어가기 때문에 처리 속도가 느려 비효율적이다.
두 번째는
보안의 문제인데, 대칭키와 비대칭키가 고정되어 있는 것보단, client 측에서 서버에 요청 시 매번 만들어내는 다른 대칭키를 통해
혹시라도 대칭키가 외부에 노출되더라도 해당 대칭키는 한 세션에서만 유효하기 때문에 보안성이 높다.
두 서버 간 통신 이전 비대칭키를 통해 안전하게 대칭키를 교환하고, 통신 간에는 대칭키를 이용하여 정보를 주고받았으니 이제 완벽한 보안이 된 것 같다!
여전히 중간자 공격으로부터 안전하지 않은 요소가 한 가지 남아있다.
client가 server와 통신하기 위해 server의 public key를 질의하는 과정에서
중간자가 개입하여 서버의 public key를 가로채고 자신의 public key를 client에게 응답하여 중간자가 server인척 속이고 client의 대칭키를 중간에 탈취하는 공격 위험이 있다.
이에 대한 자세한 내용은 다음 포스팅에 👀
위의 상황과 같이 정보가 특정 서버에서만 열람이 가능하도록 암호화하는 경우에는, 공개키를 통해 정보를 암호화하고 비공개키를 통해 복호화해야 한다.
그러나 반대로 비공개키를 통해 정보를 암호화하고 공개키를 통해 복호화하는 경우도 있는데, 이는 기밀성은 유지할 필요 없고 단지 정보의 무결성이 보장되어야 하는 상황에서 사용된다.
이에 대한 내용은 다다음 포스팅에 👀