[HTTP_NETWORK] 보안문제를 위한 HTTPS

업데이트:

이번 시간에는 HTTPS에 대해 알아보자.


1. HTTP의 약점

HTTP는 아래와 같은 약점들을 가지고 있다. 이 문제는 HTTP뿐만 아니라 다른 암호화하지 않은 프로토콜에도 공통되는 문제이다.

1) 평문(암호화하지 않은) 통신이기 때문에 도청 가능

HTTP를 사용한 통신 내용은 HTTP 자신을 암호화하는 기능은 없어 통신 전체가 암호화되지 않는다. 즉 평문으로 HTTP 메시지를 보내게 된다. TCP/IP 구조의 통신 내용은 통신 경로 도중에 이를 엿볼 수 있게 되어있다. 클라이언트와 서버 사이의 모든 경로가 본인 소유일 순 없으므로 통신 경로의 누군가 이를 엿볼 수 있다. 네트워크 상을 흐르는 패킷을 수집하는 것만으로도 도청을 할 수 있게 된다. 패킷을 수집하려면 패킷을 해석하는 패킷 캡처나 스니퍼라는 툴을 사용한다.

도청으로부터 정보를 지키기 위한 방법들이 연구되고 있는데 이 중 가장 보급된 기술은 암호화이다.

  • 통신암호화 : SSL이나 TLS라는 다른 프로토콜을 조합하여 HTTP 통신 내용을 암호화할 수 있다. SSL 등을 통해 안전한 통신로를 확립하고 나서 그 통신로를 사용해 HTTP 통신을 한다. SSL을 조합한 HTTP를 HTTPS 나 HTTP over SSL 이라 부르고 있다
  • 콘텐츠암호화 : HTTP를 사용해 운반하는 내용을 암호화하는 방법이다. 이 경우 클라이언트에서 HTTP 메시지를 암호화해서 출력하는 처리가 필요하다. 콘텐츠 암호화를 유효하게 처리하기 위해서는 클라이언트와 서버가 콘텐츠의 암호화나 복호화 구조를 가지고 있다는 것이 전제가 되므로, 유저가 사용하는 브라우저와 웹 서버에서 이용하는 것은 어렵다. 주로 웹 서비스 등에 이용되는 방법이다.

2) 통신 상대를 확인하지 않기 때문에 위장 가능

HTTP를 사용한 통신은 상대를 확인하지 않는다. 리퀘스트를 보낸 서버가 정말로 URI에 지정된 호스트인지 아닌지, 리스폰스를 반환한 클라이언트가 정말로 리퀘스트를 출력한 클라이언트인지 아닌지를 모른다는 것이다.

HTTP를 사용한 통신에서는 상대가 누구인지 확인하는 처리는 없기 때문에 누구든지 리퀘스트를 보낼 수 있다. 또한 리퀘스트가 오면 상대가 누구든지 리스폰스를 반환한다. (단 IP주소나 포트 등에서 그 웹 서버에 액세스 제한이 없는 경우)

  • 리퀘스트를 보낸 곳의 웹 서버가 원래 의도한 웹 서버인지를 알 수 없다. 위장한 웹서버일 수 있다.
  • 리스폰스를 반환한 곳의 클라이언트가 원래 의도한 리퀘스트를 보낸 클라이언트인지 알 수 없다. 위장한 클라이언트일 수 있다.
  • 통신하는 상대가 접근이 허가된 상대인지를 알 수 없다.
  • 어디의 누가 리퀘스트를 했는지를 알 수 없다.
  • 의미없는 리퀘스트도 수신하게 된다. 대량의 리퀘스트에 의한 DoS 공격을 방지할 수 없다.

HTTP에서는 통신 상대를 확인할 수 없지만 SSL로 상대를 확인할 수 있다. SSL은 암호화뿐만 아니라 상대를 확인하는 수단으로 증명서를 제공하고 있다. 증명서는 신뢰할 수 있는 제3자 기관에 의해 발행되는 것이기 때문에 서버나 클라이언트가 실재한다는 사실을 증명한다. 또한 이 증명서를 위조하는 것은 기술적으로 상당히 어렵다. 따라서 통신 상대의 서버나 클라이언트가 가진 증명서를 확인함으로써 통신상대가 내가 통신하고자 하는 상대인지 아닌지를 판단할 수 있다.

3) 완전성을 증명할 수 없기 때문에 변조 가능

완전성이랑 정보의 정확성을 말한다. 그것을 증명할 수 없다는 것은 정보가 정확한지 아닌지를 확인할 수 없음을 의미한다. 만약 리퀘스트나 리스폰스가 발신된 후 상대가 수신하기까지의 사이에서 데이터가 변조되었다고 해도 이를 알 수 없다는 뜻이다. 중간에 다른 내용으로 데이터를 변경하더라도 수신한 측에서는 이를 알아챌 수 없다. 이와 같이 리퀘스트나 리스폰스를 중간에 변조하는 공격을 중간자 공격(Man in the Middle 공격)이라 부른다.

변조를 방지하기 위해 자주 사용되는 방법은 MD5나 SHA-1 등의 해시 값을 확인하는 방법과 파일의 디지털 서명을 확인하는 방법이 있다. 파일 다운로드 서비스를 제공하는 웹 사이트에서는 PGP에 의한 서명과 MD5에 의한 해시 값을 제공하는 경우가 있다. PGP는 파일을 작성했다는 증명을 위한 서명이며, MD5는 단방향성 함수에 의한 해시 값이다. 하지만 이 방법으로도 확실히 확인할 수 있는 것은 아니다. PGP와 MD5도 수정되어 있다면 유저는 알 수 없다. 이를 확실하게 방지하기 위해서는 HTTPS를 사용할 필요가 있다. HTTP만으로는 완전성을 보증하는 것이 어렵기 때문에 다른 프로토콜을 조합하여 사용하는것 좋다.

2. HTTP + 암호화 + 인증 + 완전성 = HTTPS

HTTP 통신은 암호화되지 않은 평문으로 이루어지기 때문에 도청당하기 쉽다. 또한 통신 상대의 서버나 클라이언트를 인증하는 수단도 없다. 수신한 메시지가 변조되었을수도 있으며 실제로 의도한 상대와 통신하고있지 않을 가능성이 있다. 이러한 문제를 해결하기 위해 HTTP에 암호화나 인증 등의 구조를 더한 것을 HTTPS 라고 부른다.

HTTPS를 사용하는 통신은 웹 페이지의 로그인이나 쇼핑의 결제 화면 등에서 사용되고 있다. HTTPS를 사용한 통신은 URI에 http://가 아닌 https://를 사용한다. 또한 브라우저에서 HTTPS가 유효한 웹 사이트에 액세스하면 자물쇠 마크가 표시되는 등 HTTP와는 다르게 표시되는 경우가 있다.

HTTPS는 새로운 애플리케이션 계층의 프로토콜은 아니다. HTTP 통신을 하는 소켓 부분을 SSL이나 TLS라는 프로토콜로 대체하고 있을 뿐이다. 보통 HTTP는 TCP와 직접 통신하지만 SSL을 사용한 경우 HTTP는 SSL과 통신하고 SSL이 TCP와 통신하게 된다. 즉 SSL이라는 껍질을 쓴 HTTP가 HTTPS 인 것이다. SSL을 사용함으로써 HTTP는 HTTPS로서 암호화와 증명서와 완전성 보호를 이요할 수 있게 된다. SSL은 HTTP와 독립된 프로토콜로 네트워크 보안 기술이라 말할 수 있다.

SSL에서는 공개키 암호화 방식이라 불리는 암호화 방식을 택하고 있다. 암호화와 복호화에 하나의 키를 같이 사용하는 방식을 공통키 암호라고 부른다. 공통키 암호화 방식은 상대에게 키를 넘겨주어야 하는데 네트워크를 사용해서 키를 넘겨주면 통신이 도청되어 키를 빼앗길 수 있어 암호화의 의미가 없다. 공통키 암호의 문제를 해결하려 한 것이 공개키 암호라는 방식이다. 공개키 암호에서는 서로 다른 키 페어를 사용한다. 한쪽은 비밀키라 부르고 다른 한 쪽은 공개키라 부른다. 비밀키는 누구에게도 알려지면 안되는 키이며 공개키는 누구에게나 알려져도 괜찮은 키이다. 공개키 암호를 사용한 암호화는 암호를 보내는 측이 상대의 공개키를 사용해 암호화를 한다. 그리고 암호화된 정보를 받아들인 상대는 자신의 비밀키로 복호화를 한다. 이 방법은 비밀키를 통신으로 보낼 필요가 없어 도청에 의해 키를 빼앗길 걱정은 없다.

HTTP는 공통키 암호와 공개키 암호 양쪽 성질을 가진 하이브리드 암호 시스템이다. 키를 안전하게 교환할수만 있다면 공개키 암호만 사용해서 통신을 해도 괜찮다고 생각할 수 있지만 공개키 암호는 공통키 암호에 비해 처리 속도가 늦다. 각각의 장점을 살리기 위해 각각의 방식을 조합해어 통신을 한다. 키를 교환하는 곳에서 공개키 암호를 사용하고, 그 후의 통신에서 메시지를 교환하는 곳에서 공통키 암호를 사용한다.

아쉽게도 공개키 암호에도 문제점이 있다. 문제는 공개키가 진짜인지 아닌지를 증명할 수 없다는 것이다. 예를 들어 어떤 서버와 공개키 암호를 이용한 통신을 시작하려 할 때 수신한 공개키가 원래 의도한 서버가 발행한 공개키인지 확신할 수 없다. 이 문제를 해결하는데 인증기관과 그 기관이 발행하는 공개키 증명서가 이용되고 있다. 인증 기관이란 클라이언트와 서버가 모두 신뢰하는 제3자 기관이다. 유명한 인증 기관에는 VeriSign사가 있다.

인증기관은 다음과 같이 이용된다. 먼저 서버의 운영자가 인증 기관에 공개키를 제출한다. 인증 기관은 제출된 공개키에 디지털 서명을 하고 서명이 끝난 공개키를 만든다. 그리고 공개키 인증서에 서명이 끝난 공개키를 담는다. 서버는 이 인증기관에 의해 작성된 공개키 인증서를 클라이언트에 보내고 공개키 암호로 통신을 한다. 증명서를 받은 클라이언트는 증명 기관의 공개키를 사용해 서버의 공개키를 인증한 것이 진짜 인증 기관이라는 것과 서버의 공개키를 신뢰할 수 있다는 것을 알 수 있다. 여기서 사용되는 인증 기관의 공개키는 안전하게 전달되어야 하는데 통신 중에 어떤 방법으로도 100% 안전한 방법은 없다. 따라서 많은 브라우저가 주요 인증 기관의 공개키를 사전에 내장한 상태로 출시되고 있다.

증명서의 역할은 서버가 올바른 통신 상대임을 증명하는 것이지만, 상대방이 실제로 있는 기업인지를 확인하는 역할도 있다. 이러한 역할을 가진 증명서를 EV SSL 증명서라 한다. EV SSL 증명서는 세계 표준의 인정 가이드라인에 의해 발행되는 중명서이다. 운영하는 조직의 실재성을 확인하는 방법을 엄격히 규정하고 있기 때문에 웹 사이트의 신뢰성을 더욱 더 높일 수 있다. 브라우저 주소창이 녹색으로 변하면 EV SSL로 증명된 사이트라는 것을 시각적으로 알 수 있다. 그리고 주소창 옆에는 SSL 증명서에 기재된 조직명 및 증명서를 발행한 인증기관 명이 표시된다.

HTTPS에서는 클라이언트 증명서도 이용할 수 있다. 이를 통해 서버 증명서와 같이 서버가 통신하는 상대가 의도한 클라이언트인지 증명하는 클라이언트 인증을 할 수 있다. 하지만 이는 몇 가지 문제가 있는데 클라이언트 증명서의 입수와 배포가 이해 해당한다. 유저가 클라이언트 증명서를 유료로 구입해야 하며, 유저 수에 따라 비용이 들게 된다. 또한 이는 직접 설치해야 한다. 안정성이 매우 높은 인증 기능을 제공할 수 있지만 특정 용도로만 사용되고 있다. (비용을 들일 필요가 있는 곳에만) 또 다른 문제는 클라이언트 인증서는 클라이언트의 실재를 증명할 뿐, 사용자의 존재 유무를 증명하는 증명서는 아니다. 즉 클라이언트 증명서가 있는 컴퓨터를 사용할 권한이 있다면 누구든지 이용할 수 있다.

SSL은 인증기관을 신용할 수 있다는 전제로 이루어져 있다. 하지만 잘못 발행된 증명서로 해도 믿을 수 있는 인증 기관의 서명이 있기 때문에 브라우저는 올바른 인증서로 인식한다. 서버로 위장할 때 사용되더라도 유저가 알아채기 어렵다.

OpenSSL 등의 소프트웨어를 사용하면 누구든지 직접 인증 기관을 구축할 수 있다. 하지만 인터넷 상에서는 구실을 하지 못하며 쓸모가 없다. 독자적으로 구축한 인증 기관은 위장의 가능성이 없다고 볼 수 없기 때문이다. 직접 구축한 인증기관이므로 [나는 xxx입니다] 라고 말하는 것과 같다. 신뢰할 수 있는 제3자 기관이 인증을 해야 실제로 서버의 증명이 가능하다고 볼 수 있다.

3. HTTPS의 통신 흐름

1) 클라이언트가 Client Hello 메시지를 송신하면서 SSL 통신을 시작. 메시지에는 클라이언트가 제공하는 SSL 버전을 지정하고, 암호 스위트로 불리는 리스트(사용하는 암호화 알고리즘이나 키 사이즈 등)이 포함

2) 서버가 SSL 통신이 가능한 경우 Server Hello 메시지로 응답. 클라이언트와 같이 SSL 버전과 암호 스위트를 포함. 서버의 암호 스위트 내용은 클라이언트에서 받은 암호 스위트의 내용에서 선택된 것

3) 서버가 Certificate 메시지를 송신. 메시지에는 공개키 증명서가 포함

4) 서버가 Server Hello Done 메시지를 송신. 최초의 SSL 네고시에이션이 끝났음을 통지

5) SSL 최초 네고시에이션이 종료되면 클라이언트가 Client Key Exchange 메시지로 응답. 메시지에는 통신을 암호화하는데 사용되는 Pre-Master secret이 포함되어 있음. 이 메시지는 3단계에의 공개키 증명서에서 꺼낸 공개키로 암호화 되어있음

6) 클라이언트는 Change Cipher Spec 메시지를 송신. 이 메시지는 이후의 통신은 암호키를 사용해 진행한다는것을 나타냄

7) 클라이언트는 Finished 메시지를 송신. 이 메시지는 접속 전체의 체크 값을 포함. 네고시에이션이 성공했는지는 서버가 이 메시지를 올바르게 복호화 되는지 여부에 따라 결정됨

8) 서버에서 마찬가지로 Change Cipher Spec 메시지를 송신

9) 서버에서 마찬가지로 Finished 메시지를 송신

10) 서버와 클라이언트의 Finished 메시지 교환이 완료되면 SSL에 의해 접속이 확립. 이제부터 애플리케이션 계층의 프로토콜에 의해 통신을 시작. 즉 HTTP 리퀘스트를 송신

11) 애플리케이션 계층의 프로토콜에 의한 통신으로 HTTP 리스폰스를 송신

12) 마지막에 클라이언트가 접속을 끊음. 이 경우 close_notify 메시지를 송신. 그 후 TCP FIN 메시지를 보내 TCP 통신을 종료.

위 흐름에 애플리케이션 계층의 데이터를 송신할 때는 MAC이라 부르는 메시지 다이제스트를 덧붙일 수 있다. MAC을 이용해 변조를 감지할 수 있어 완전성 보호를 실현할 수 있다.

4. SSL과 TLS

HTTPS에서는 SSL과 TLS라 부르는 두 개의 프로토콜이 사용되고 있다. SSL3.0을 기반으로 한 TLS1.0이 측정되어 TLS1.1, TLS1.2 등이 있다. TLS는 SSL를 바탕으로 한 프로토콜이지만 이를 총칭해 SSL이라 부르기도 한다.

HTTPS에도 문제가 있는데 SSL을 사용하면 처리가 늦어진다는 점이다. SSL 통신이 지연되는 이유는 통신 속도가 떨어진다는 점과 CPU나 메모리 등의 리소스를 다량으로 소비함으로써 처리가 늦어진다는 점이다. 네트워크의 부하는 HTTP를 사용하는 경우와 비교해 2~100배 정도 느려질 수 있다. TCP 접속과 HTTP의 리퀘스트, 리스폰스 외에 SSL에 필요한 통신이 추가되기 때문에 전체적으로 처리해야 할 통신 량이 증가하게 된다. 또한 SSL은 반드시 암호화 처리를 하기 때문에 서버나 클라이언트는 암호화나 복호화를 위한 계산을 할 필요가 있다. 그렇기 때문에 서버나 클라이언트의 리소스를 소비하게 되어 HTTP의 부담이 커지게 된다.

느려지는 것에 근본적인 해결 방법은 없기 때문에 SSL 액셀레이터라는 하드웨어를 이용해 이러한 문제를 해결하기도 한다. SSL 액셀레이터는 SSL을 처리하기 위한 전용 하드웨어로 소프트웨어로 SSL을 처리할 때보다 몇 배 빠른 계산을 할 수 있다.

그럼 왜 HTTP를 아직도 쓰고 있을까?

HTTP가 안전하다면 왜 모든 웹은 항상 HTTPS를 사용하지 않을까? 이유는 위에서 언급한 속도, 리소스 등의 문제 때문이다. 따라서 민감한 정보를 다루지 않는 통신에서는 HTTP를 사용한다. 특히 액세스가 많은 웹 사이트에서 암호화를 하면 그 부하가 상당하다. 이러한 경우 모든 콘텐츠를 암호화하지 않고 일부만 암호화 함으로써 리소스를 절약하고 있다. HTTPS를 사용하려면 증명서가 필요한데 이를 사용하기 위해서는 CA에서 증명서를 구입해야 한다. 일반적으로 연간 수십만원 정도 필요한데 이러한 구입 비용이 부담되는 개인 웹사이트 등에서는 HTTP만 선택하는 경우도 있다.