[CS Study] - 6주차

subin·2022년 7월 14일
0

  • HTTP와 HTTPS의 차이점
  • DNS round robin 방식
  • Blocking/Non-blocking & Synchronous/Asynchronous
  • Load Balancing
  • CORS

HTTP와 HTTPS의 차이점

HTTP (HyperText Transfer Protocol)

인터넷 상에서 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규약

HTTP는 HyperText Transfer Protocol의 줄임말로, 서버와 클라이언트간에 데이터를 주고 받는 프로토콜이다. 처음에는 문서간에 링크를 통해 연결할 수 있는 HTML을 전송하는 프로토콜로 시작했지만, 지금은 텍스트, 이미지, 영상, JSON 등 거의 모든 형태의 데이터를 전송할 수 있고 서버간에 데이터를 주고 받을 때도 대부분 HTTP를 사용한다.

세상에 등장한지 벌써 30년이나 된 HTTP는 1997년에 만들어진 HTTP/1.1가 가장 보편화 되어있으며, 현재는 HTTP/2를 거쳐 HTTP/3까지 개발된 상태이다. TCP를 개선해서 만들어진 UDP가 HTTP/3 기술에 사용된다.

HTTP의 구조

HTTP는 애플리케이션 레벨의 프로토콜로 TCP/IP 위에서 작동한다. HTTP는 상태를 가지고 있지 않는 Stateless 프로토콜이며 Method, Path, Version, Headers, Body 등으로 구성된다.

HTTP는 보안적으로 안전한가?

HTTP 통신은 클라이언트와 서버간의 통신에 있어서 별다른 보안 조치가 없기 때문에, 만약 누군가 네트워크 신호를 가로챈다면 HTTP의 내용은 그대로 외부에 노출된다. 중요 정보가 없는 프로젝트라면 문제가 되지 않겠지만 아래의 그림과 같이, 고객의 개인정보나 비밀을 취급하는 서비스라면 큰 보안적 허점이 될 것이다.

이처럼 누군가 패킷을 훔쳐보는 스니핑(Sniffing) 공격에 취약하다. HTTP 통신에서는 Wire Shark를 통해 패킷을 확인하면 개인정보가 그대로 서버로 전송되는 것을 볼 수 있다. 때문에, 서버와 클라이언트 간 데이터를 보호하기 위해서는 인증서를 통해 패킷을 암호화 한 뒤에 전송해야 한다. 이런 문제를 해결하기 위해 등장한 것이 HTTPS이다.

HTTPS (HyperText Transfer Protocol Secure)

인터넷 상에서 정보를 암호화하는 SSL 프로토콜을 사용해서 클라이언트와 서버가 자원을 주고 받을 때 쓰는 통신 규약


HTTPS는 HTTP에 데이터 암호화가 추가된 프로토콜이다. 요즘은 거의 모든 사이트의 주소창에서 자물쇠 표시를 볼 수 있다. HTTPS가 적용되었다는 것을 알려주는게 바로 아래의 자물쇠 표시이다. HTTPS가 옛날부터 보편화되어 있지는 않았다. 처음에는 전자상거래 등 고객의 중요 정보를 다루는 사이트 위주로 사용되었다.

그러다가 2014년 구글에서 HTTP를 HTTPS로 변환하라고 권고하기 시작하였다. 귀찮은 작업을 시킬때는 그에따른 보상이 있어야하는데, 구글은 HTTPS를 적용하는 사이트들에게 SEO(검색 엔진 최적화)에 있어서 가산점을 주겠다고 했었다. 사용자 정보의 안전성도 보장받고, 사용자들의 웹사이트 유입도 늘릴 수 있으니 HTTPS로 변환할 이유는 충분했을 것이다.

HTTPS는 HTTP와 다르게 443번 포트를 사용하며, 네트워크 상에서 중간에 제3자가 정보를 볼 수 없도록 암호화를 지원하고 있다.

HTTPS는 어떤 방식으로 보안 이슈를 해결하는가?

기존의 HTTP 프로토콜은 전송계층의 TCP 위에서 동작한다. 여기서 SSL (Secure Sockets Layer) 이라는 보안계층이 전송계층 위에 올라간다. HTTPS는 SSL위에 HTTP를 얹어서 보안이 보장된 통신을 하는 프로토콜이다. 이 통신 방식을 SSL 암호화 통신이라고도 한다.

SSL (Secure Socket Layer)

SSL은 웹사이트와 브라우저(혹은, 두 서버) 사이에 전송된 데이터를 암호화하여 인터넷 연결 보안을 유지하는 표준 기술이다. 이는 해커가 개인 정보 및 금융 정보를 포함한 전송되는 모든 정보를 열람하거나 훔치는 것을 방지한다. 쉽게 말해, 네트워크 통신을 할 때 보안을 제공하기 위해 설계된 암호 규약이다.

TLS (Transport Layer Socket)

사실 SSL과 TLS는 같다. 처음에 네스케이프에 의해 발명된 SSL이 표준화가 되며 바뀐 이름이 TLS이다. TLS 1.0이 SSL 3.0을 계승한 것인데, 아직 TLS라는 이름보다는 SSL이 더 널리 사용된다.

대칭키 암호화와 비대칭키 암호화

HTTPS는 대칭키 암호화 방식과 비대칭키 암호화 방식을 모두 사용하고 있다. 각각의 암호화 방식은 다음과 같다.

암호화?
암호화라는 것은 무엇인가 남들은 읽을 수 없게, 비밀이 유지되어야 할 때 사용한다. 암호화를 하기 위해서는 일종의 키(Key)가 필요하다. 키는 문자가 될 수도 있고, 숫자가 될 수도 있다. 암호화는 [키] + [데이터]를 이용하여 [암호화 된 데이터] 를 만들어 내는 것이다. 따라서 키가 단 한 글자라도 다르다면 암호화의 내용도 전혀 다르다.


복호화 또한 마찬가지로 [암호화된 데이터] + [키] 를 이용하여 [데이터] 를 얻는 것이다. 때문에, 복호화에서도 키(key)는 꼭 필요하다. 키를 모른다면 절대 복호화를 할 수 없다. 이때 암호화 복호화에 사용하는 이 키는 서로 동일할 수도, 다를 수도 있다.

1. 대칭키 암호화 (Symmetric key algorithm)

대칭키 암호화란, 암호화를 하는 키와 복호화를 하는 키가 동일한 방식이다. 이때 암호화와 복호화에 동시에 사용되는 이 키를 대칭키라고 한다.

위에서 "0823"이라는 키로 암호화 복호화를 동시에 하고 있는 것을 볼 수 있다. 즉, 위의 커플은 대칭키 "0823" 을 이용한 대칭키 암호화를 사용하고 있는 것이다.

대칭키 암호화의 단점을 살펴보자.

대칭키는 상대방도, 나도 서로 공유를 해야하기 때문에 대칭키를 전달하는 과정에서 제3자가 훔쳐볼 위험이 있다. 만약 대칭키가 해킹 당한다면 복호화가 가능하니, 데이터도 누출되게 된다.

이처럼 대칭키 암호화 방식에서는, 대칭키를 상대에게 전달하는 과정에서 해킹당할 위험이 있다.

이러한 대칭키 암호화의 근본적인 문제를 해결하고자 나온것이 다음에 소개하는 비대칭키 암호화 방식이다.

2. 비대칭키 암호화 (Asymmetric key algorithm)
하나의 키를 갖는 대칭키 암호화 방식과 달리, 비대칭키 암호화 방식은 한 쌍의 키를 갖는다. 한마디로 비대칭키 암호화 방식에서는 키가 2개이다. 이 두개의 키로 각각 암호화, 복호화를 할 수 있다.

만일 A, B라는 두 개의 키가 있다면 A키로 암호화 한 데이터는 B키로만 복호화를 할 수 있다. 또한 B키로 암호화한 데이터는 A키로만 복호화를 할 수 있다. A키로 암호화 한 데이터를 A키로 복호화 할 수 없고, B키도 마찬가지이다.

통상적으로 비대칭키 방식에서 가지는 두 개의 키에서 하나는 공개 키(Public key), 다른 하나는 개인키(비밀키, Private key)라고 부른다. 이렇기 때문에 공개키는 암호화를, 개인키를 복호화를 한다고 알려져 있는데, 그렇지 않다.

위의 그림처럼, 공개키로 암호화하면 개인키로 복호화 할 수 있고, 개인키로 암호화하면 공개키로 복호화 할 수 있다. 이렇듯 한 쌍의 키로 암호화, 복호화를 하는 방식을 RSA 알고리즘 이라고 한다.

이 RSA 알고리즘을 통해 어떻게 데이터를 암/복호화 하여 주고 받는지 알아보자.

그림으로도 이해가 가겠지만, 간단히 설명하자면 남자와 여자가 RSA 알고리즘을 통해 메시지를 주고 받는다. 그렇다면 남자는 공개키와 개인키를 가질 것이고, 여자 또한 공개키와 개인키를 가질 것이다. 이제 여자는 남자에게 자신의 공개키를 알려주고, 남자도 여자에게 자신의 공개키를 알려준다. 이 과정에서 공개키가 해킹당한다 해도 개인키를 알지 못하면 복호화를 할 수 없어 안전하다.

이제, 남자의 공개키를 받은 여자는 전송하고자 하는 메시지를 남자의 공개키로 암호화 하여 전송한다. 그러면 남자는 받은 데이터를 자신의 개인키로 복호화하여 볼 수 있다. 반대로 남자가 여자에게 데이터를 보낼 때는 여자의 공개키로 암호화를 해서 보내고, 여자는 받은 데이터를 자신의 개인키로 복호화 하여 보는 것이다.

왜 대칭키 방식과 비대칭키 방식을 같이 사용할까?

언뜻 보기에는 비대칭키 방식이 완벽해 보여서 굳이 대칭키 방식과 혼용할 필요가 있을까라는 생각이 들었다.

하지만, RSA 알고리즘을 이용한 암호화 방식은 복잡한 수학적 원리로 이루어져 있어서, CPU 리소스를 크게 소모한다는 단점이 있다. 이 때문에, RSA 비대칭키 방식으로만 통신을 하기에는 성능상 어려움이 있다고 한다.

처음에 대칭키를 서로 공유하는 통신은 RSA 비대칭키 방식을 이용하고, 실제 통신을 할 때는 CPU 리소스 소모가 적은 대칭키 방식으로 데이터를 주고 받는다.

아래 그림을 보면 이해가 수월할 것이다.

비대칭키 암호화 방식으로 대칭키 "1234"를 비밀스럽게 공유하고, 대칭키를 안전하게 공유했으니 대칭키 암호화 방식을 이용하여 메세지를 주고 받는 내용이다.

TLS가 제공하는 이점들

1. 기밀성 (암호화)
위에서 계속 얘기했던 내용에 해당하는 항목이다. 서버와 주고 받는 데이터가 스니핑 되는 것을 방지한다. 패킷이 오가는 것을 훔쳐 볼 수는 있어도 안전하게 암호화 된 패킷이라 복호화 할 수 없기 때문에 데이터는 훔쳐볼 수 없다.

2. 데이터 무결성
통신 도중 데이터가 제3자에 의해 악의로 변경될 일이 없다. 기밀성과 같은 선상에서 보면 된다. 서로의 대칭키를 RSA 알고리즘을 통해 안전하게 공유한 후에 암호화하여 통신하기 때문에 제3자가 대칭키를 알아내지 않는 한 중간에서 암호화된 데이터를 임의로 수정하지 못한다.

3. 서버 인증
기밀성과 데이터 무결성은 암호화 알고리즘을 통해 가능하다고 보여진다. 근데 만약 위의 암호화 방식으로만 서버와 클라이언트가 통신을 한다고 가정해보자. 서버와 나는암호화를 통해 통신하기 때문에 아무도 데이터를 훔쳐볼 수도, 건들 수도 없겠지! 라고 생각할 수 있지만, 만약 서버가 신뢰할 수 없는 서버라면 말이 달라진다.

보이스피싱을 생각해보면 쉽게 이해가 될 것 같다. 보이스피싱범들이 웹사이트를 실제 검찰 사이트와 똑같이 만들어두고 주민번호를 입력하라고 한다. 여기서 내가 주민번호를 치면 보이스피싱범들이 만들어 놓은 서버에 내 주민번호를 보내는 것이다.

이처럼 내가 데이터를 서버에 아무리 암호화하여 보낸다 한들, 서버가 가짜로 만들어 놓은 쓰레기통 서버라면 큰 문제가 될 것이다.

이처럼, 서버와 클라이언트 간 통신을 할 때는 서버가 신뢰할 수 있는 서버라는 것을 확인하는 작업이 필요하다.

이럴 때 사용하는 것이 바로 인증서이다.

인증서

인증서란 서버가 신뢰할 수 있는 진짜 서버 임을 확인하기 위해 필요한 것이라고 말했다. 인증서에는 다음과 같은 정보들을 포함하고 있다.
1. 서비스 정보 (인증서를 발급한 CA, 서비스의 도메인 등)
2. 서버 측 공개키 (공개키, 공개키 암호화 방법)
3. 지문, 디지털 서명 등

티스토리의 인증서를 보면 아래와 같다.

앞서 말했듯 서버의 공개키, 서명, 지문, 발급자 정보 등이 포함되어 있다.
이것들의 역할에 대해서 알아보기 전에, 인증서가 어디서 어떻게 생성되는지 먼저 알아보자.

CA (Certificate Authority)

CA는 인증서를 발급해주는 기관으로, Root Certificate라고 부르기도 한다. CA는 아무 기업이나 할 수 있는 게 아니라, 신뢰성이 엄격하게 공인된 기업들만 할 수 있다. TLS 통신을 하려면 이 CA를 통해서 인증서를 발급받아야 한다.

CA는 자체적으로 공개키비밀키를 가지고 있다. CA의 비밀키는 절대 누설 되어서는 안 되며, 실제 어떤 CA 기관은 이 비밀키가 누설되어 파산한 기관도 있다.

CA에서 인증서를 발급 받으려면

서버가 CA로부터 인증서를 발급받는 방법에 대해서 알아보자.

먼저, 발급 받고자 하는 기관은 자신의 사이트 정보(도메인 등)공개키를 CA에게 제출한다. 그러면 CA는 검증을 걸친 후에 발급 받고자 하는 기관의 공개 키를 해시(SHA-256 등) 한다. 이렇게 해시한 값을 Finger Print이라고 한다.
이제 이 지문을 CA의 비밀키로 암호화 하고, 인증서의 발급자 서명으로 등록한다.

이렇게 서명된 것을 디지털 서명이라고 한다. 이제 CA는 서버에게 디지털 서명, 발급자 등이 등록되어 있는 인증서를 발급해준다.

이러한 방식처럼, 상위 인증 기관이 하위 인증서가 포함하고 있는 공개키를 상위 기관의 비밀키로 암호화하여 상호 보증하게 되는 것을 인증서 체인이라고 한다.

내가 발급받은 CA 기관이 Root CA가 아니라면, 이 CA 기관마저 또 상위 CA에게 인증서를 발급받은 것 이다. 보통 3단계에 걸쳐서 인증서 체인이 일어나는데,

1. tistory.com의 인증서는 그 상위 인증서인 Thawte TLS RSA CA G1의 인증기관의 비밀키로 암호화 된 것이며,
2. Thawte TLS RSA CA G1 인증서는 그 상위 인증서인 DigiCert Global Root G2의 인증기관의 비밀키로 암호화 된 것이다.
3. DigiCert Global Root G2는 상위 인증기관이 없는 Root CA이기 때문에 Self-Signed 되어 있다.

Self-SIgned (스스로 보증) 이란?
자신의 인증서를 해시한 후, CA가 아닌 자신의 비밀키로 암호화 하여 서명으로 등록하는 것을 말한다.

CA 인증 없이 인증서를 생성할 수 있을까?

가능하다. 심지어 TLS 통신도 가능하다. 물론, 신뢰성은 떨어지겠지만 아예 불가능한 일은 아니다. CA 인증과 상관없이 발행하는 인증서를 사설 인증서라고 한다. 이 사설 인증서는 Root CA처럼 self-signed 되어 있다.

때문에 보증 기관이 없으며, 따라서 누구도 보증해주지 않는 인증서이다. 이러한 사설 인증서를 사용하여도 TLS 통신을 할 수 있다. 대신 공인 기관에서 발급받은 인증서가 아니라는 정도는 사용자에게 알려줘야 한다.

가끔 홈페이지 들어가면 "신뢰할 수 없는 사이트입니다."라는 안내문을 보았을 것이다. 사설 인증서를 사용할 경우 공인 인증서가 아니기 때문에 그런 안내문이 뜬다.

SSL(TLS) 인증서로 서버를 인증하는 방법

CA에서 발급받은 인증서를 통해 서버의 신뢰성을 인증한다고 했다. 근데 클라이언트는 이 인증서가 CA에서 발급받은 것인지, 중간에 누가 조작한 것인지 알 수 없다. 그렇다면 어떠한 방식으로 인증이 되는걸까?

먼저 알아 둘 것은, 클라이언트들은 CA 리스트를 이미 갖고 있다. OS를 설치할 때 PC에 포함되거나 브라우저가 포함하고 있다.

여기서 CA 리스트란, 공인으로 인증된 CA 기관들의 리스트들로, 그들의 공개키도 함께 갖고 있다.

서버를 인증하는 방법은 다음과 같다.

1. 서버: 야 우리 믿을 수 있는 서버라고 인증서 발급 받자!

서버는 자신이 믿을 수 있는 서버임을 인증하기 위해 CA에서 인증서를 발급받고자 한다. 그러기 위해선 자신의 사이트 정보(도메인 등)과 사이트의 공개키를 CA에 제출해야 한다. 그러면 CA는 검증을 걸친 후 제출받은 서버의 공개키를 해시하여 CA의 비밀키로 암호화 한다. 그리고 서버에게 이런 정보들이 들어 있는 인증서를 발급해 준다. 서버는 이제 자신이 진짜 서버임을 인증해 줄 인증서를 갖고 있는 것이다.

2. 클라이언트: 야 서버! 나랑 통신하고 싶으면 인증서 내놔!
클라이언트가 이 서버에 접속하려고 한다. TLS 통신에서 클라이언트와 서버는 서로 몇번 인사를 주고 받으며 서버는 CA에서 발급 받은 자신의 인증서를 클라이언트에게 전달한다.

그런데, 누군가 중간에 해킹해서 인증서를 바꿔치기 했다거나, 교묘하게 인증서의 공개키를 해킹범의 공개키로 바꿨을 수도 있다. 그렇다면 인증서의 무결성은 어떻게 입증할까?

먼저, 클라이언트는 이 인증서가 자신이 가진 CA 리스트에 있는 기관에서 발급받은 것인지 확인한다.

이것이 확인되면, CA 기관의 공개키로 서버 인증서의 서명을 복호화 한다. (CA는 자신의 비밀키로 인증서를 암호화 하였으니, 공개키로 복호화가 가능하다.) 디지털 서명을 복호화 하면, 인증서 내용을 해시한 값이 나올 것이다.

이처럼 디지털 서명을 CA 기관의 공개키로 복호화 하여 나온 해시 값과, 공개키를 해시한 값(지문)이 일치 한다면, 인증서가 위조되지 않았음을 인증하는 것이다. 당연히 일치하지 않는다면 인증서가 위조되었다는 의미이다.

그림을 보면 이해하는 데 도움이 될 것이다.

만약, 인증서의 공개키가 임의로 수정된 값이라면 이 공개키를 해시한 값은 서명을 복호화한 값(원본 공개키의 해시 값)과 전혀 다른 값이 나올 것이다. 이런 방식으로 서버 인증서의 무결성을 검증할 수 있다.

3. 클라이언트: 서버 너 믿을만한 놈이었구나? 이제 암호화 통신하자!
클라이언트는 이제 서버가 CA 인증기관에서 인증받은 신뢰할 수 있는 서버임을 알았다. 또한, 인증서 안에 들어 있는 서버의 공개키도 알았다. 이제 서로 통신을 주고받기 위해 클라이언트는 자신이 사용할 '대칭 키'를 서버에게 전달해 주어야 한다. 이전에 공부했던 TLS 암호화 방식을 통해서 말이다.

클라이언트는 서버의 공개키로 대칭키를 암호화 하여 서버에게 보내고, 서버는 자신의 비밀키로 이를 복호화 하여 클라이언트의 대칭키를 알아내는 것이다. 그러고 나면 클라이언트와 서버는 통신을 할 수 있게된다.

HTTPS 통신 흐름

  1. 애플리케이션 서버(A)를 만드는 기업은 HTTPS를 적용하기 위해 공개키와 개인키를 만든다.
  2. 신뢰할 수 있는 CA 기업을 선택하고, 그 기업에게 내 공개키 관리를 부탁하며 계약을 한다.
    CA 란? : Certificate Authority로, 공개키를 저장해주는 신뢰성이 검증된 민간 기업
  3. 계약 완료된 CA 기업은 해당 기업의 이름, A서버 공개키, 공개키 암호화 방법을 담은 인증서를 만들고, 해당 인증서를 CA 기업의 개인키로 암호화해서 A서버에게 제공한다.
  4. A서버는 암호화된 인증서를 갖게 되었다. 이제 A서버는 A서버의 공개키로 암호화된 HTTPS 요청이 아닌 요청이 오면, 이 암호화된 인증서를 클라이언트에게 건내준다.
  5. 클라이언트가 main.html 파일을 달라고 A서버에 요청했다고 가정하자. HTTPS 요청이 아니기 때문에 CA 기업이 A서버의 정보를 CA 기업의 개인키로 암호화한 인증서를 받게 된다.
    CA 기업의 공개키는 브라우저가 이미 알고있다. 세계적으로 신뢰할 수 있는 기업으로 등록되어 있기 때문에, 브라우저가 인증서를 탐색하여 해독이 가능한 것이다.
  6. 브라우저는 해독한 뒤 A서버의 공개키를 얻게 되었다. 이제 A서버와 통신할 때는 얻은 A서버의 공개키로 암호화해서 요청을 날리게 된다.

HTTPS도 무조건 안전한 것은 아니다. (신뢰받는 CA 기업이 아닌 자체 인증서 발급한 경우 등)

이때는 HTTPS지만 브라우저에서 주의 요함, 안전하지 않은 사이트와 같은 알림으로 주의 받게 된다.

Reference

profile
한번뿐인 인생! 하고싶은게 너무 많은 뉴비의 deep-dive 현장

0개의 댓글