선행 지식
CA (Certificate Authority): 인증서를 발급해주는 기업. SSL을 적용하기 위해 인증서가 필요한데, 인증서는 서비스의 정보, 서버 측의 공개키가 포함되어 있다.Handshake: 통신 시작 시 클라이언트와 서버가 서로 신분을 확인하고, 필요한 정보를 주고받는 과정이다.- 대칭키, 비대칭키
HTTP 통신의 허점
우리가 기본적인 HTTP 프로토콜을 사용하는 웹서버(웹앱서버)를 띄워 로그인 API를 호출할 때, 아이디와 비밀번호를 서버로 보내면 입력한 텍스트는 누구든 알아볼 수 있는 평문으로 보내진다. 만약 누군가가 중간에서 이 정보를 탈취한다면 유저의 아이디와 비밀번호를 고스란히 알게 된다.
이러한 치명적인 보안적 허점을 해결하기 위해 인증서를 발급받고, 그 인증서를 기반으로 데이터를 인코딩해서 주고받는다. 이는 다른 누군가가 탈취하더라도 알아볼 수 없게 된다. 이 방법이 HTTPS이다.
HTTPS란?
기존의 HTTP는 TCP/IP 위의 애플리케이션 계층에서 사용되는 프로토콜이다. HTTPS는 TCP/IP 계층 위에 SSL(TLS)를 얹어 보안을 강화한 프로토콜 방식이다. 이를 통해 모든 HTTP 요청과 응답은 암호화된다.

만일 HTTPS에서 대칭키를 사용할 경우 최초 한 번은 서버에서 클라이언트로 암호화에 사용할 키를 전달해야 하는데, 그 과정에서 암호화 키를 누군가 탈취한다면 누군가 암호화/복호화 가능한 키를 가지고 있기 때문에 암호화 통신을 하더라도 무용지물이 된다. (누군가 데이터를 복호화해서 정보를 다 해석할 수 있다.)
비대칭키를 사용할 경우 서버는 개인키/공개키를 둘 다 가지고 있고, 클라이언트에서 요청할 때 공개키만 준다. 이 공개키로 암호화한 데이터는 서버만 가지고 있는 '개인키'로만 복호화 가능하다. 그리하여 누군가 공개키를 탈취하고 데이터를 탈취하더라도 데이터를 복호화할 수 없게 된다. 하지만 처리 속도가 느려 성능에 문제가 생길 수 있다.
HTTPS는 각각의 단점을 보완하기 위해 대칭키/비대칭키 방식을 혼합하여 사용한다. 최초 한 번 서버가 공개키/개인키를 가지고 있다가 클라이언트가 요청 시 공개키를 전달해준다. 클라이언트는 실제 데이터 전달에 사용할 대칭키를 공개키로 암호화하여 서버에 전달한다. 서버는 개인키를 사용해 대칭키를 복호화하고 그 후 대칭키로 실제 통신이 이루어진다. (이러한 방식을 사용하면 최초 핸드셰이킹 시에만 비대칭키 알고리즘을 사용하니 속도 저하의 문제도 해결되고, 대칭키 전달 시 대칭키를 비대칭키로 암호화하니 중간에 대칭키가 탈취되어도 누군가가 복호화할 수 없는(사용할 수 없는) 키가 되기에 보안적으로도 안전하다.)
이러한 대칭키는 HTTPS 통신 과정에서 세션키로 불린다.
SSL 및 TLS
앞서 SSL은 TCP/IP 계층의 위에서 동작하는 프로토콜, 인터넷을 통해 전송되는 데이터의 인증, 암호화, 복호화를 위한 프로토콜(계층)이라는 것을 간접적으로 알아봤다.
사실 SSL은 TLS(Transport Layer Security)라는 또 다른 프로토콜의 이전 버전이다. 그래서 TLS 암호화 및 TLS Handshake라고 부르는 게 바람직하지만, SSL이 더 잘 알려져있기에 그냥 SSL로 부르거나 TLS/SSL로 명명하기도 한다. 필자는 SSL이라고 명시하겠다.
TCP 3-way Handshake 과정
- 클라이언트는 서버에게 접속 요청을 위한 메시지(SYN)를 보낸다. 18503218같이 의미없는 난수를 같이 보낸다. (SEQ넘버)
- 서버는 클라이언트에게 SYN 요청을 받은 다음, 연결을 수락(ACK)한다. 서버에서도 85291953같이 난수를 보낸다. (ACK넘버)
- 클라이언트는 서버에 접속 수락 확인(SYN)을 보낸다. 이때 서버측에서 넘겨준 ACK넘버에 1을 더해 같이 보내준다. TCP 연결이 성립, 서버는 ESTABLISHED 상태가 된다.
SSL Handshake 과정
HTTPS는 TCP 위에 SSL 계층이 있는 구조이므로 TCP 3-way Handshake 과정을 거친 후 SSL Handshake 과정에 들어간다.
SSL Handshake 과정은 아래와 같은 순서로 이루어진다.
1. Client : Client Hello
클라이언트가 먼저 서버에 접속해 말을 건넨다. 브라우저는 TCP 3-way Handshake를 통해 해당 웹서버가 HTTPS를 사용한다는 것을 알게 되며, 아래 정보를 이 단계에서 서버로 보낸다.
- 브라우저가 사용하는 SSL 버전 정보
- 브라우저가 지원하는 암호화 방식 모음 (
cipher suite) - 브라우저가 순간적으로 생성한 임의의 난수 (숫자)
- 만약 이전에 SSL Handshake가 완료돤 상태라면, 그때 생성된
Session ID - 기타 확장 정보 (Extension)
참고) cipher suite란 보안의 목표 달성을 위해 사용하는 방식들을 패키지의 형태로 묶어놓은 것을 의미한다. (암호화 알고리즘, 전달 대상 인증, 메시지 무결성 확인 알고리즘 등)
2. Server : Server Hello
서버 또한 클라이언트의 인사에 응답하면서, 아래 정보를 클라이언트에 제공한다.
- 브라우저의 암호화 방식 중, 서버가 선택한 암호화 방식 (
cipher suite) - 서버의 공개키가 포함된 SSL 인증서 (인증서는 CA의 비밀키로 암호화되어 발급된 상태)
- 서버가 순간적으로 생성한 임의의 난수 (숫자)
- 클라이언트 인증서 요청 (선택사항)
3. Client : 서버의 SSL 인증서 신뢰성 확인
브라우저에는 검증된 CA들의 정보 및 CA가 만든 공개키가 이미 설치되어 있다. 서버가 보낸 SSL 인증서를 내장된 CA 공개키로 복호화하여 정말 CA가 만든 것인지 확인한다.
만약 위조된 인증서이거나 등록된 CA가 아니라면 이 과정에서 발각되며, 브라우저에 경고를 보낸다.
4. Client : 클라이언트의 난수, 서버의 난수를 활용해 premaster secret 생성
클라이언트는 자신이 이전에 생성했던 난수와 서버가 보내준 난수를 사용해 premaster secret이라는 데이터를 만들고, SSL 인증서에 딸려온 웹서버의 공개키로 이 premaster secret를 암호화한다. 또한 이를 서버로 전송한다.
5. Server : premaster secret 복호화
서버는 클라이언트에게서 받은 premaster secret을 자신의 개인키(비밀키)를 활용하여 복호화한다. 이를 사용해 세션 키를 생성한다.
앞에 말했던 HTTPS에서 쓰이는 대칭키가 이 세션키인 것이다. 이 세션키를 사용해 브라우저-서버 사이에 주고받는 데이터를 암호화/복호화한다.
6. SSL Handshake 종료
이로써 SSL Handshake는 정상적으로 완료되었고, 이제 웹상에서 데이터를 주고받을 때 세션 키를 이용해 암호화/복호화할 수 있다.
HTTPS 통신이 완료되는 시점에 서로에게 공유된 세션 키를 폐기한다. 만약 세션이 여전히 유지되고 있다면 브라우저는 세션 ID만 서버에게 알려주면 된다. (1에서 언급)
참고) SSL 핸드셰이크 과정은 키 교환 알고리즘 종류마다 다르지만, 원리는 같다. 위는 RSA 키 교환 알고리즘을 따랐다.
HTTPS는 100% 안전한가
HTTPS는 웹에서 보안을 적용하기 위한 가장 기본 단계이기에, 이것 덕분에 보안이 완벽해진다고 할 수 없다.
웹 서버가 해커의 공격에 의해 루트 권한을 탈취당했다면, 웹 서버의 모든 기밀 데이터를 열람할 수 있는 권한이 넘어갈 수 있다.
또한 HTTPS는 전달 구간에 대한 보안 기술인데, 전달 구간 중간에 해커가 중간자 공격(Man in the middle attack)을 수행할 수 있는 취약점이 있다면 전달 내용이 고스란히 노출될 수 있다.