우아한테크코스 레벨3 프로젝트를 진행하면서 HTTPS를 적용해야하는 요구사항이 있었는데요. 적용하면서 HTTPS HandShake에 대해 알아보았습니다.
대부분의 웹사이트들은 HTTP에 Secure을 적용한 HTTPS를 통해서 통신합니다. HTTPS로 통신하기 위해 Client와 Server는 HandShake라는 과정을 수행합니다. 이에 대해 알아보겠습니다.
먼저, HTTPS에 대해 간략하게 짚어보겠습니다.
예를 들어 아이디, 비밀번호를 서버에 전송하여 로그인을 할 때, 3자에게 아이디와 비밀번호가 노출될 수 있기 때문에 이를 암호화합니다.
브라우저에서 google.com에 접속했을 때, google.com 이라는 도메인은 검증된 CA(Certificate Authority)에서 신뢰할 수 있는 곳이라고 인증한 인증서가 있기 때문에 사용자들에게 안전한 사이트라는 것을 보장해줍니다.
그렇다면 HTTPS의 통신 과정은 어떻게 이루어질까요?
설명에 앞서, 암호화와 복호화 방식에 대해서 알아보겠습니다.
기본적으로 HTTPS에서는 데이터를 특정 키를 통해서 암호화하여 전송
하고, 수신한 곳에서 특정 키를 통해서 복호화
하는 방식을 사용합니다.
초기에는 암호화와 복호화하는데 대칭키(동일한 키)를 사용했습니다. 똑같은 A라는 키를 나눠가지고, 암호화하고 복호화하는데 사용하는 것이죠.
대칭키는 치명적인 문제가 있습니다. 해당 키를 공유하는 시점에 누군가가 키를 탈취
한다면, 암호화 된 데이터를 쉽게 복호화하고 확인
할 수 있다는 것이죠. 사실상 보안이 보장되지 않는 것이라 여겨도 될 것 같습니다.
이런 문제를 해결하기 위해 수학자들이 비대칭키라는 방식을 고안해냈습니다.
비대칭키는 위와 같이 동일하지 않는 두 개의 키를 사용하는 방식입니다.
Server는 개인키(서버만 가지고 있는 키)를 가지고 해당 개인키와 쌍을 맺고 있는 공개키를 Client들에게 제공합니다.
개인키로 암호화한 데이터는 공개키로만 복호화할 수 있고, 공개키로 암호화한 데이터는 개인키로만 복호화할 수 있습니다. 따라서, 악의적인 사용자가 공개키를 가지고 있어도 클라이언트가 서버로 전송하는 데이터(공개키로 암호화된 데이터)를 복호화할 수 없습니다.
요점만 말하자면, 공개키를 통해 개인키를 구하려고 해도 엄청 오랜 시간이 걸린다고 합니다. 공개키를 통해 개인키를 구하지 못하도록 키에 매우 큰 수가 할당됩니다. 1초에 100만 번 연산을 수행하는 슈퍼컴퓨터라 할지라도 계산하는 데 약 30년이 걸린다고 합니다.
자세한 내용은 아래 블로그에 수식으로 설명이 되어있으니 참고하시면 좋을 것 같습니다.
https://velog.io/@ann0905/HTTPS-1.암호화에-대하여대칭키-공개키
여기까지가 기본적인 대칭키와 비대칭키의 개념입니다.
Google, Naver와 같은 사이트가 신뢰할 만한 곳이라고 인증서를 발급해주는 기관이 있습니다. 이를 CA, Certicate Authority라고 합니다. 아무곳이나 CA를 할 수 있는 것이 아니라, 여러 절차를 밟아야 CA가 될 수 있습니다. GoDaddy, Comodo, Let’s Encrypt 등이 있습니다. 우리가 사용하는 브라우저에는 CA들의 목록과 CA의 공개키들이 저장
되어 있습니다.
실제 HTTPS는 조금 더 복잡한 과정들을 거칩니다. 차근차근 살펴보겠습니다.
사용자가 google.com을 입력한 시점에, Client는 아직 google의 Server가 신뢰할 만한 곳인지 모릅니다. 따라서, Client와 Server가 일련의 절차를 통해서 신뢰할 수 있는지 확인합니다. 이를 HandShake라고 합니다.
먼저, Client는 임의의 데이터
를 서버에게 전송합니다.
임의의 데이터를 받은 Server도 Client에게 임의의 데이터
를 전송합니다. 이때, 해당 Server의 인증서
를 함께 보냅니다. 여기서 Client가 Server의 인증서를 보고 신뢰할만한 사이트인지 판단합니다.
판단할 때, 비대칭키 시스템을 사용합니다.
Server가 Client에게 전송한 인증서는 CA에게 발급 받은 것입니다. 해당 인증서는 CA의 개인키로 암호화되어 있습니다. 따라서, 위에서 말했던 브라우저에 저장된 CA의 공개키들 중 하나로 해당 인증서를 복호화할 수 있다면 해당 사이트는 신뢰할 수 있다고 판단
하는 것입니다.
그렇다면 Server의 공개키는 어떻게 얻을까요?
앞서 진행한 HandShake에서 복호화된 인증서에 Server의 공개키가 포함
이 되어 있습니다.
하지만, 인증서 복호화를 통해 얻은 Server의 공개키를 사용해서 공개키-개인키 방식으로 암호화-복호화를 해서 통신을 진행하지 않습니다. 대칭키에 비해 비대칭키를 통한 암호화-복호화가 시간이 훨씬 오래 걸리기 때문입니다. 위에서 말했듯이, 비대칭키 알고리즘에는 키에 매우 큰 수가 할당이 됩니다. 큰 수로 암호화-복호화를 진행하기 때문에 대칭키에 비해 성능적인 단점이 존재합니다.
따라서, 대칭키의 상대적으로 빠른 연산과 비대칭키의 안전성을 조합한 방식을 사용합니다.
Client는 HandShake에서 주고받은 임의의 데이터를 조합해서 pre master key라는 키를 생성합니다. 그리고, pre master key를 인증서에서 얻은 공개키로 암호화해서 Server로 전송합니다.
Server는 자신의 개인키로 복호화해서 pre master key를 얻습니다.
그 후, pre master key를 통해 master key를 양쪽에서 도출해내고 master key를 통해 session key를 생성하여 양쪽 모두 대칭키를 얻습니다.
왜 pre master key를 바로 사용하지 않고 master key를 통해서 session key를 생성하는지가 궁금해서 찾아보았는데 알아내지 못했습니다…😢 아시는 분이 있다면 공유해주시면 감사하겠습니다!
이렇게 Handshake가 끝이나고 HTTPS로 통신할 수 있는 환경이 갖추어집니다.
끗!
https://sdesigner.tistory.com/85
https://www.youtube.com/watch?v=H6lpFRpyl14