
HTTP와 HTTPS
HTTP(Hyper Text Transfer Protocol)는 서버/클라이언트 모델에 따라 데이터를 주고받기 위한 프로토콜이다. 즉, HTTP는 인터넷에서 하이퍼 텍스트를 교환하기 위한 통신 규약이며, 80번 포트를 사용한다.
HTTP의 문제점
- HTTP는 평문 통신이기 때문에 도청이 가능하다.
- HTTP는 통신 상대를 검증하지 않기 때문에 피싱이나 중간자 공격(Man-in-the-Middle Attack)에 취약하다.
- 데이터의 무결성을 보장하지 않기 때문에, 데이터가 전송 중에 변경되거나 조작될 수 있다.
HTTPS(HTTP over SSL, HTTP over TLS, HTTP Secure)는 HTTP에 데이터 암호화가 추가된 프로토콜이며, HTTP와 달리 443번 포트를 사용한다. HTTPS의 가장 큰 특징은 HTTP가 가지고 있던 보안 문제를 해결한다는 것이다. 즉, HTTPS는 암호화, 인증, 완전성 보장을 지원한다.
SSL과 TLS
넷스케이프가 SSL(Secure Socket Layer)을 발명하고, 점차 폭넓게 사용되다가 표준화 기구인 IETF의 관리로 넘어가면서 TLS(Transport Layer Security)로 이름이 바뀌었다. TLS 1.0은 SSL 3.0을 계승한 것이다.
물론 TLS가 발전하면서 차이점도 존재하지만, 동작 방식은 유사하니 이 글에서는 같은 의미로 설명한다.
대칭키 암호화와 비대칭키 암호화
대칭키 암호화

- 클라이언트와 서버가 동일한 키를 사용하여 암호화/복호화를 진행한다.
- 키가 노출되면 매우 위험하지만, 연산 속도가 빠르다.
그런데, 이 대칭키를 어떻게 양쪽이 공유할 수 있을까? 대칭키가 중간에 갈취당한다면 큰 문제가 될 것이다. 이러한 대칭키 암호화 방식의 한계로, 비대칭키 암호화 방식이 등장하였다.
비대칭키(공개키) 암호화

- 두 개의 키 중 하나로 암호화하면, 나머지 키로만 복호화가 가능하다.
- 예를 들어 A 키와 B 키가 하나의 쌍이라면, A 키로 암호화하면 B 키로 복호화할 수 있고, B 키로 암호화하면 A 키로 복호화할 수 있다.
- 둘 중 하나를 공개키라 하고, 다른 하나를 개인키로 정한다.
- 클라이언트는 공개키를 가지고, 서버는 개인키를 가진다.
- 공개키는 이름에서 알 수 있듯이 누구나 가질 수 있다. 대신, 개인키는 서버만이 가지고 있다.
- 키가 노출되더라도 비교적 안전하지만, 연산 속도가 느리다.
우리가 네이버에서부터 정보를 받았을 때, 이게 진짜 네이버에서 온 정보인지 어떻게 알 수 있을까?
- 네이버에서 우리에게 보내는 정보 중 일부가 네이버의 개인키로 암호화되어 있다.
- 네이버의 개인키로 암호화된 정보를 복호화할 수 있는 것은 우리가 가진 네이버의 공개키뿐이다.
- 만약 우리가 가진 네이버의 공개키로 온전히 복호화할 수 있다면, 그것은 네이버에서 온 정보일 것이다.
이 예시는 단순히 인증을 이해하기 위한 예시이며, 비대칭키 암호화를 사용하면 이렇게 인증을 할 수 있다는 것만 확인한다. 실제로 서버의 인증은 이후에 설명할 SSL 인증서를 통해 진행된다.
SSL 인증서
SSL 인증서는 클라이언트와 서버 간의 통신을 제3자가 보증해주는 전자화된 문서이다. 클라이언트가 서버에 접속한 직후에 서버는 클라이언트에게 이 인증서 정보를 전달한다. 클라이언트는 이 인증서가 신뢰할만한 것인지 검증한 후 다음 절차를 진행한다.
이 SSL 인증서를 통해 앞서 언급한 HTTP의 보안 문제를 해결한다. 즉, SSL 인증서의 기능은 크게 다음과 같다.
- 클라이언트가 접속한 서버가 신뢰할 수 있는 서버임을 보장한다.
- SSL 통신에 사용할 공개키를 클라이언트에게 제공한다.
CA(Certificate Authority)
앞서 말했듯, 인증서의 역할 중 하나는 클라이언트가 접속한 서버가 신뢰할 수 있는 서버임을 보장하는 것이다. 그럼 누가 보증을 해줄까? 이를 인증하는 공인된 민간 기업들이 있다. 이러한 기업들을 CA라고 한다. SSL을 통해 암호화된 통신을 제공하려는 서비스는 CA를 통해 인증서를 구입해야 한다.
SSL 인증서의 내용
- 서비스의 정보 (인증서를 발급한 CA, 서비스의 도메인 등)
- 클라이언트가 접속한 서버가 클라이언트가 의도한 서버가 맞는지에 대한 내용
- 서버 측의 공개키 (공개키의 내용, 공개키의 암호화 방법)
- 서버와 통신할 때 사용할 공개키와 그 공개키의 암호화 방법
서비스의 도메인, 공개키와 같은 정보는 서비스가 CA로부터 인증서를 구입할 때 제출해야 한다. 이 내용들은 CA에 의해서 암호화되는데, 이때 사용하는 암호화 방식이 공개키(비대칭키) 방식이다. CA는 자신의 CA 개인키를 이용해서 서비스에서 제출한 인증서를 서명한다. CA의 개인키는 절대로 유출되어서는 안 된다. 그리고, 우리가 사용하는 브라우저에는 CA들의 목록과 그들의 공개키가 내장되어 있다.
SSL 인증서가 서비스를 보증하는 방법
- 웹 브라우저가 서버에 접속할 때 서버는 제일 먼저 클라이언트에게 인증서를 제공한다.
- 브라우저는 이 인증서를 발급한 CA가 자신이 내장한 CA의 리스트에 있는지를 확인한다.
- 확인 결과 서버에서 받은 인증서가 내장된 CA 리스트에 포함되어 있다면, 해당 CA의 공개키를 이용해서 인증서를 복호화한다.
- CA의 공개키를 이용해서 인증서를 복호화할 수 있다는 것은 이 인증서가 CA의 개인키에 의해 암호화된 것을 의미한다.
- 해당 CA의 개인키를 가지고 있는 CA는 해당 CA밖에 없기 때문에, 서버가 제공한 인증서가 CA에 의해 올바르게 발급된 것이라는 것을 의미한다.
- 즉, CA에 의해 발급된 인증서라는 것은 접속한 사이트가 CA에 의해 검토되었다는 것을 의미하고, CA의 검토를 통과했다는 것은 해당 서비스가 신뢰할 수 있다는 것을 의미한다.
이렇게 해서 인증서가 서버의 신뢰성을 제공하는 방법을 알아봤다. 그런데 의문점이 남는다. 인증서에 포함된 서버의 공개키는 어떤 용도로 사용될까?
SSL의 동작 방법
비대칭키 암호화 방식만을 사용하면 컴퓨팅 파워가 많이 소모되기 때문에 SSL 인증서에서는 대칭키 방식과 비대칭키 방식 모두를 사용한다. 클라이언트와 서버가 주고받는 실제 정보는 대칭키 방식으로 암호화하고, 이 대칭키를 비대칭키 방식으로 암호화하여 클라이언트와 서버가 공유한다.
- 실제 데이터 : 대칭키 방식
- 대칭키 방식의 키 : 비대칭키 방식
컴퓨터와 컴퓨터가 네트워크를 통해 통신을 할 때 내부적으로 3단계를 거친다.
Handshake → 전송 → 세션 종료
이러한 과정에서 SSL이 어떻게 데이터를 암호화하여 전달하는지 알아보자.

-
SSL Handshake
-
Client Hello: 클라이언트가 서버에 접속하고, 클라이언트는 서버에 다음과 같은 정보를 전달한다.
- 클라이언트에서 생성한 랜덤 데이터
- 클라이언트가 지원하는 암호화 방식
- 세션 아이디: 이미 SSL Handshaking을 했다면 비용과 시간 절약을 위해 기존 세션을 재활용하는데 이를 위한 식별자 (이 과정에서는 크게 중요하지 않다.)
-
Server Hello: 서버는 Client Hello에 대한 응답으로 Server Hello 과정을 거치며, 클라이언트에 다음과 같은 정보를 전달한다.
- 서버에서 생성한 랜덤 데이터
- 서버가 지원하는 암호화 방식
- 인증서
-
클라이언트는 서버에게서 받은 인증서가 CA가 발급한 것인지를 확인하기 위해 클라이언트에 내장된 CA 리스트를 확인한다.
만약, 그 리스트에 인증서가 없다면 사용자에게 경고 메시지를 출력한다. 인증서가 CA에 의해 발급된 것인지 확인하기 위해 내장된 CA의 공개키로 복호화를 시도한다. 만약 복호화에 성공하면 CA의 개인키로 암호화된 것이기 때문에 신뢰할 수 있다.
클라이언트는 자신이 생성한 랜덤 데이터와 서버에서 받은 랜덤 데이터를 조합하여 pre master secret이라는 키를 생성한다. 이 pre master secret이라는 키를 서버에도 전달해야 하는데, 이때 공개키 방식으로 암호화한다.
복호화된 인증서 안에는 서버가 생성한 공개키가 들어있다고 했었다. 클라이언트는 성공적으로 인증서를 복호화하면 서버 측에서 만든 공개키를 획득하게 된다. 클라이언트는 인증서에서 얻은 서버의 공개키로 pre master secret 값을 암호화하여 서버에 전달한다.
-
서버는 그 공개키에 대한 개인키를 가지고 있기 때문에 pre master secret 값을 얻어낼 수 있다. 이제 클라이언트와 서버 모두 pre master secret 값을 공유하게 되었다. 클라이언트와 서버는 각각 일련의 과정을 통해 pre master secret에서 master secret 값을 만들어내고, 이 master secret으로 세션키를 생성한다. 이 세션키를 이용하여 서버와 클라이언트는 실제 데이터를 대칭키 방식으로 암호화하여 주고받는다.
-
-
전송(세션)
실제로 클라이언트와 서버가 데이터를 주고받는 단계이다. 이전 단계에서 얻은 세션키를 이용하여 대칭키 방식으로 데이터를 암호화하고 상대방에게 전달한다. -
세션 종료
데이터 전송이 끝나면 서로에게 SSL 통신이 끝났음을 알린다. 세션 종료 후 세션키를 폐기하여 보안을 유지한다.