HTTPS

Posted by yunki kim on October 8, 2021

  기존 HTTP는 클라이언트, 서버 사이의 요청, 응답을 평문으로 전송하기 때문에 중간에 이런 데이터들을 가로채서 볼 수 있었다(와이어샤크 등을 통해). 이런 문제를 해결하기 위해 클라리언트, 서버는 암호화 통신 채널을 설정하고 여기서 평문 HTTP 메시지를 선송해 정보 유출을 막는데 이것이 HTTPS이다.

  이런 암호화채널을 SSL(Secure Socket Layer)라고 하며 이를 개선한 것이 TLS(Transport Layer Security)이다. SSL은 넷스케이프가 개발한 프로토콜이고, TLS는 IETF표준이다. 현재 SSL의 모든 버전은 여러가지 보안 문제가 존재하기 때문에 사용되지 않는다. 그 대신 TLS를 사용한다. 

  HTTP/2를 사용하는 웹사이트가 많아지고 있고 HTTP/2에서 보안 연결을 선택이다. 아지만 대부분의 브라우저가 HTTP/2, TLS만을 지원하기 때문에 HTTP/2를 사용한다면 TLS는 사실상 필수이다. 

 

HTTPS를 사용하는 이유

  HTTPS는 다음과 같은 이점이 존재한다.

    1. 기밀성: HTTPS는 인터넷과 같은 공공 매체에서 두 참여자 간의 통신을 보호한다. HTTPS를 사용하지 않는다면 WI-FI Access-point를 운영하는 사람은 액세스 포인트를 사용하는 사람이 입력한 개인 정보를 볼 수 있다.

    2. 무결성: HTTPS는 변조되지 않은 정보로 목적지에 도달한다. 대역폭 절약을 위해 미디어 파일의 품질을 일부러 저하시키거나, 데이터를 위조하는 행위를 할 수 없다.

    3. 인증: HTTPS를 통해 웹사이트의 진위 여부를 확인할 수 있다. 웹사이트를 접속할 때 이 웹사이트가 WI-FI Access-point를 운영하는 사람이 가짜로 만은 웹사이트인지, 실제 웹사이트인지를 판별할 수 있다. 

    4. 모던 브라우저에 존재하는 더 많은 기능을 사용할 수 있다.

      웹에는 수 많은 기능들이 추가되고 있고 이런 기능들은 안전한 연동을 통해 유저의 데이터를 보호해야 한다. 이런 기능들로는 블루투스, USB 등이 있다. 

    5. 검색 엔진 최적화.

      검색엔진이 검색 결과를 도출할 때 HTTPS는 HTTP보다 우선순위를 갖는다. 

 

HTTP 동작 과정

  HTTPS를 설명하기 전에 HTTP가 어떤식으로 동작하는 집고 넘어가자. 

  HTTP는 클라이언트-서버 모델을 사용하고 응답-요청 프로토콜을 이용해 비동기적으로 통신한다. 브라우저는 클라이언트 역할을 하고 아파치, nginx 는 서버 역할을 한다. 서버는 데이터를 호스팅하고 클라이언트의 요청에 맞는 데이터를 응답한다.

  클라이언트와 서버가 메시지를 주고 받는 과정은 연결 초기화로 시작한다. 그 후 TCP slow start kicks in 이라는 프로세스를 시작한다. 이 과정에서 데이터는 패킷들로 전송되고 여러번의 요청-응답을 실행한다. TCP slow start kicks in이 필요한 이유는 클라이언트가 얼만큼의 밴드폭을 감당할 수 있는지를 서버가 모르기 때문이다. 따라서 서버는 TCP slow start kicks in을 사용해 한번의 요청-응답이 있을 때 마다 한번에 전송하는 데이터의 양을 클라이언트 밴드폭이 감당할 수 있는 최대 양까지 점증적으로 늘린다. 통상적으로 TCP slow start kicks in의 최초 패킷 사이즈는 16kb이며 한번의 요청-응답이 있을 때 마다 2배씩 증가시킨다. 대부분의 연결에서 이 데이터의 양은 4MB까지 늘어난다.

 

HTTPS Stack

  HTTPS를 사용하기 위해서는 TLS 인증서가 서버에 존재해야 한다. SSL 또는 TLS 인증서는 랜덤으로 생성된 키들(공개, 개인키)을 서버에 저장한다. 이 중 공개키는 복호화에 사용되는 개인키와 클라이언트로 검증된다. 

  HTTPS는 HTTP와 같은 계층 구조를 가지지만 바로 아래에 TLS계층이 하나 더 있다.

SSL 패킷 구조

HTTP Handshake

 브라우저가 HTTPS에 연결되면 서버는 인증서를 응답하고 브라우저는 다음 항목들로 해당 인증서의 유효여부를 체크한다. 만약 아래 항목 중 하나라도 유효하지 않는다면 유저는 에러를 통지받는다.

   1. 소유자의 정보는 사용자가 요청한 서버 이름과 일치해야 한다.

   2. 신뢰할 수 있는 인증기관에서 서명된 인증서야 한다.

  HTTP가 사용되면, 일련의 핸드셰이크들이 실행된다. 초기 요청은 인증을 위해 서버에 보내진다. 서버가 해당 서버는 올바른 서버라는 응답을 보내게 되면 클라이언트는 client hello를 요청한다. 이때 이 커뮤니케이션은 암호화 된다. 이는 암호화 키를 교환하기 위해서이다. 이 시점에서 암호문 해독에 대한 커뮤니케이션을 할 수 있다. 이런 초기 핸드셰이크 과정은 수 밀리세컨드 안에 수행된다. 

  HTTPS 핸드셰이크가 끝나면 클라이언트, 서버 사이의 모든 통신(전체 URL, 데이터(평문, 바이너리), 쿠키, 다른 헤더들)은 암호화 된다. 하지만 서버의 도메인이나 호스트는 암호화 되지 않는다. 이는 연결이 시작되면 대상 서버에 HTTP요청을 해서 보안 연결을 만들기 때문이다.

TCP 3 way-handshake

  TCP는 서버, 클라이언트 사이간에 동기화를 위해 three-way handshake를 사용한다. 이는 TCP/IP 프로토콜을 이용해 통신을 하는 애플리케이션의 안전한 데이터 전송을 위해 먼저 상대 컴퓨터와 사전에 세션을 수립하는 과정이다.

  1. client syn: 클라이언트가 데이터를 보내기 전 동기화 요청

  2. server syn/ack: 서버가 응답

  3. client ack: 클라이언트가 응답.

 

Client hello

  TLS handshake과정의 첫 단계이다. 이 단계는 클라이언트와 서버가 TLS 통신을 하기 위한 최초 협상 단계이다. 와이어샤크를 통해 캡쳐한 client hello 패킷은 다음과 같은 구조를 가지고 있다.

  이 구조는 다음과 같은 의미를 가지고 있다.

  1. record layer는 Content Type, Version, Length 총 3개 파트로 나뉘어져 있고 Content Type은 패킷의 프로토콜 종류를 나타낸다. 따라이 이 예시는 Handshake 프로토콜이며 프로토콜 버전은 TLS 1.0이고 그 길이는 595이다 라는 의미이다.

  2. handshake 프로토콜 영역은 크게 Handsake Type, Length, Body부분으로 나뉘어진다. Handsake Type은 TLS handshake 과정 중에 현재의 과정을 의미한다. 따라서 이 예시는 handshake 과정 중 Client Hello 패킷이며, TLS버전은 1.2, 길이는 591이다 라는 의미이다.

  3. Random은 SSL Handsake 과정이 끝난 후 데이터 함호화, 복호화를 위한 비밀키의 재료이다. 난수이며 서버에게 전달된다.

  4. 만약 기존에 SSL Handsake 과정을 맺은 이력이 있으면 Session ID가 존재한다. Client는 존재하는 값에 대해 명시해 보낸다. 만약 이 값이 0이면 기존에 SSL Handsake 과정을 맺지 않았다는 의미이므로 SSL Handsake과정을 전부 수행해야 한다.

  5. 클라이언트에서 지원이 가능한 Cipher Suite 값 리스트를 서버에게 전달한다. 그 후 서버와 클라이언트는 저 리스중 하나를 사용해 통신을 한다.

  Cipher Suite는 다음과 같은 구조를 이루고 있다: 

    SSL/TLS_키 교환 암호 알고리즘_인증 알고리즘_WITH_대칭암호 알고리즘_블록 암호 운용 방식_해시 알고리즘.

    키 교환 암호 알고리즘: 서버, 클라이언트 간에 키를 교환할 알고리즘

    인증 알고리즘: 서버, 클라이언트간에 교환한 인증서를 확인하는 알고리즘

    대칭 알고리즘: 실제 데이터를 암호화 하는 알고리즘

    블록 암호 운용 방식: 데이털르 암호화 할때 항꺼번에 암호화 하는 것이 아닌 블록 단위로 암호화 한다. 이 때 블록단위로 나뉘어진 암호                      화  패킷을 조합해 데이터를 추측하는 것을 방지하는 알고리즘

    해시 알고리즘: 서로 상대방이 암호화 한것이 맞는지 확인하는 알고리즘

 

Server Hello

Serve Hello 역시 Client Hello와 비슷한 구조를 가지고 있으며 그 예시는 다음과 같다.