이전 글
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 1편 LAN/WAN, TCP/IP 4 계층, 패킷 교환 방식
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 2편 DNS
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 3편 Port(포트), Socket(소켓)
앞의 세 편을 통해서,
1) 모든 네트워크 디바이스는 연결되어 있으며(LAN/WAN), 상호간에 통신하는 약속이 정해져있고(TCP/IP 4계층 모델), 큰 데이터를 여러 작은 데이터로 쪼개서 통신한다.(패킷 교환 방식)
2) DNS 프로토콜을 통해 도메인 주소에 대응하는 IP 주소를 얻어온다.
3) 알게된 IP 주소와 HTTPS의 Well Known 포트 번호인 433을 가지고 구글 프로세스로 찾아가, TCP 소켓을 연결한다.
까지 알아보았습니다.
이제 연결했으니 진짜 통신하는구나! 하시겠지만, 사실 아직 한 가지가 더 있는데요,,, 바로 SSL(TLS) 프로토콜로 암호화하는 작업이 필요합니다.
SSL이란? (feat. HTTPS vs HTTP)
순서가 조금 어지럽긴하지만, SSL을 이해하기 위해서는 잠깐 HTTP와 HTTPS를 얘기하고 넘어가야합니다. HTTP에 대해서는 다음 편에서 더 구체적으로 다루겠지만, 가볍게 설명을 드리자면 이것은 TCP/IP 4계층 중에 Application Layer에 속하며, 프로세스끼리의 통신을 담당합니다. 사실 우리가 접하는 거의 모든 웹페이지가 HTTP 통신을 기반으로 작동이 됩니다.
그럼 이름이 비슷한 HTTPS는 무엇일까요? HTTPS는 이름에서도 유추할 수 있듯 'HTTP + S'입니다. 여기서 'S'는 Secure의 약자로, HTTP에서 보안기능이 추가된 것을 의미합니다. HTTP 일반 텍스트를 사용하기 때문에, 하나의 통신 데이터가 오고가는 과정에서 누군가 이 통신을 가로챈다면 바로 어떤 내용인지 확인할 수 있고, 아이디나 비밀번호와 같은 중요 정보인 경우에는 큰 피해가 생길 수도 있습니다. 그래서 HTTPS에서는 HTTP의 일반 텍스트를 암호화해서 보냄으로서, 중간에 누가 보더라도 이해할 수 없도록 고안한 프로토콜입니다. 그리고 이 암호화하는 프로토콜이 바로 SSL(또는 TLS)이며, 말하자면 HTTPS는 SSL(TSL)을 사용한 HTTP입니다.
HTTP로 데이터를 보내기 전에, 먼저 암호화를 해야하니, TCP 소켓 연결 이후 본격적인 통신이 시작되기 전에 SSL 프로토콜을 통해 어떤 방식으로 암호화를 할지 서버와 얘기를 진행해야하며, 이것을 협상이라고 부릅니다.
SSL(Secure Socket Layer) / TLS(Transport Layer Security)
들어가기에 앞서 왜 SSL과 TLS를 혼용해서 사용하는지 간략히 말씀드리겠습니다. 원래 이 암호화 프로토콜 SSL은 넷스케이프라는 회사에서 만들었고, 표준화가 되어가면서 국제표준화기구인 IETF로 관리가 변경되면서 명칭이 TLS로 바뀌었지만, 관습상 SSL을 더 많이 사용하고 있습니다.
암호화 방식: 대칭키와 공개키 (feat. 인증서)
어떻게 암호화를 할까요? SSL에서 사용하는 암호화 방식은 '대칭키'와 '공개키'방식을 섞어서 사용합니다. 두 명칭에 공통적으로 등장하는 '키'의 개념을 살펴보자면, 어떤 정보를 암호화하는데 사용하는 특정한 알고리즘에 사용된 일련의 문자입니다. 예를 들어, 'ABC'라는 데이터를 알파벳으로 1자리씩 옮겨서 'BCD'라고 암호화한다고 했을 때, '1'이 키가 될 수 있는 것입니다. 여기서는 가장 간단한 형태를 예시로 들었지만, 실제로 사용하는 암호화 알고리즘은 훨씬 복잡하고, 긴 글의 경우 해독하는데 꽤 시간이 걸립니다.
그럼 '키(key)'가 무엇인지 알았으니, '대칭'키과 '공개'키 방식을 살펴보겠습니다. 사실 바로 앞에서 살펴본 예시가 '대칭키'를 사용한 암호화입니다. '1'이라는 '키'를 송신자와 수신자, 둘만 가지고 있고(대칭적), 이 키를 이용해서 암호화/복호화를 진행합니다. 하지만, 문제점이 있습니다. 이 방식을 사용하면 '키'가 없이는 정보를 복호화할 수 없으니 안전하지만, 이 암호를 해독하는 '키'를 안전하게 전달하는 것이 까다롭죠. 둘만 있을 때 몰래 키를 나누어 가진 다음 나중에 멀리서 이용하면 좋겠지만, 인터넷 상에서는 어려운 일이니까요.
그래서 등장하게 된 것이 '공개키'입니다. 이것은 암호화 하는 키와 복호화하는 키를 각각 따로 만들고, 암호화하는 키를 공개(public key)하고 복화하는 키를 숨겨두는(private key) 방식입니다.(암호키를 숨기고, 복호키를 공개하는 것도 가능합니다.) 누구든지 공개키로 암호화를 할 수 있지만, 일단 암호화된 정보는 꼭 private key가 필요합니다. 이것을 활용하는 방식은 대략 다음과 같습니다. 서버가 복호화하는데 사용하는 private key를 잘 숨겨두고, 암호화하는 public key를 클라이언트에 제공하는 것입니다. 그럼 클라이언트는 받은 공개키로 암호화를 하여, 누가 이 정보를 탈취해도 의미를 해석할 수 없도록하고, 이 암호화된 정보를 서버에 보내서 서버가 private key로 복화화해서 사용하는 것입니다. 이런 방식으로 아이디와 비밀번호 등을 전달하면 안전하겠지요.
이 공개키 방식은 이렇게 암호화하는 용도 이외에도 한 가지 용도가 더 있습니다. 바로 '인증서' 기능입니다. 바로 예시를 들어 설명해보겠습니다. 방금은 공개키를 암호화하는데 사용했지만, 반대로 private key로 암호화하고 public key로 복호화할 수도 있습니다. 서버가 이렇게 암호화된 정보를 공개키와 함께 전송하고, 클라이언트가 받은 정보를 공개키로 복호화하는데 성공한다면, 이 정보가 특정 private key로 암호화됐다는 것을 증명할 수 있고, 이 public key와 1:1로 매칭된 private key를 가지고 있는 주체를 인증할 수 있는 것입니다.
하지만, 암호화할 때 사용한 private key의 소유주가 누구인지를 확신할 수 없습니다. 그레서 이런 것을 인증해주는 기관이 필요하고, 이 관을 CA라 부릅니다.
공개키 인증 기관 CA(Certificate Authority)
CA 인증 기관입니다. HTTPS를 사용하여 자신이 안전하다는 것을 인증하기를 원하는 서버는 이 CA 기관에 인증 신청을 합니다. CA는 저마다의 기준으로 해당 서버를 평가해서 안전하다고 판단을 하면, CA가 공인을 하고 인증서를 발급합니다. 이 인증서는 CA만 가지고 있는 비공개키로 암호화가 되어 있습니다. 따라서 CA의 공개키로 해당 인증서를 복화하는데 성공한다면, CA에 의해 인증된 기관임을 증명하는 것입니다.
또한 CA는 여러 기관이 있고, 브라우저가 신뢰할 수 있는 CA들의 리스트와 CA의 공개키를 가지고 있습니다. 서버가 클라이언트에게 인증서를 보내줄 때, 어느 CA에서 발급받았는지 알려주서, 브라우저가 CA 리스트와 비교해보고, 가지고 있는 공개키로 복호화를 시도함으로서 확인작업을 진행합니다.
How it works?
그럼 어떤 과정을 거쳐 이런 작업이 이뤄지는지 한 단계씩 알아보겠습니다. (여기서 부터가 TCP 소켓을 연결하고 난 직후 벌어지는 일입니다.)
1. Client Hello
클라이언트가 Client Hello 패킷을 보냅니다. 이 패킷에 들어가는 내용 중 중요한 내용은 아래와 같습니다.
1) 클라이언트가 생성한 랜덤 숫자: 나중에 공개키를 만들 때의 재료로 사용됩니다.
2)클라이언트(브라우저)가 제공하는 암호화 기법들의 리스트: 브라우저마다 다를 수 있습니다.
2. Server Hello
서버가 Server Hello 패킷을 보냅니다. 이 패킷에 들어가는 내용 중 중요한 내용은 아래와 같습니다.
1) 서버가 생성한 랜덤 숫자: 마찬가지로 나중에 공개키를 만들 때의 재료로 사용됩니다.
2) 클라이언트가 보내준 암호화 기법 들 중 자신도 지원하면서 가장 안전하다고 판단한 암호화 기법: 앞으로 이 방식으로 암호화/복호화 합니다.
3) SSL 인증서
3. 인증서 검증
클라이언트는 앞서 살펴본 것처럼 인증서를 검증하는 작업을 진행합니다.
1) 서버가 보내 준 인증서의 인증기관(CA)이 어디인지 확인
2) 이 기관이 브라우저에 내장된 CA리스트에 있는지 확인
3) 있다면, 해당 CA의 공개키로 인증서 복호화 시도
4) 성공했다면, 해당 CA에 의해 인증된 기관임을 검증
5) 복호화된 인증서에는 서버가 private key를 가지고 있는 public key(암호화키)와 해당 공개키와 사용할 암호화 방법
4. pre master secret 전송
1) 랜덤 숫자 생성(pre master secret)하여 인증서에 있던 공개키로 암호화하여 서버에 보냄. (이 숫자는 클라이언트와 서버만 알고 있음)
5. session key(대칭키) 생성
1) 처음 주고 받은 랜덤 숫자와 pre master secret을 조합하여 앞으로 통신에 사용할 대칭키 생성.
(서버는 클라이언트가 보낸 pre master seceret을 private key로 복화하여 똑같은 작업 수행)
2) 이 대칭키는 서버와 클라이언트만 알고 있음
6. 세션
이 session key(대칭키)를 사용해서 Application Layer에서 통신할 메시지를 암호화/복호화함.
7. 종료
통신이 끝나면 이 키를 폐기함
공개키와 대칭키를 섞어 사용하는 이유
사실 공개키만을 이용하면 될 텐데, 왜 굳이 이런 번거로운 작업을 진행할까요? 그 이유는 공개키를 암호화/복화하는데 컴퓨팅 파워가 많이 필요하기 때문입니다. 따라서, 공개키를 이용해서 대칭키를 암호화/복화하는 방법으로 대칭키를 얻어 사용하는 방법을 통해 조금 복잡하더라도 효율성을 높일 수 있습니다.
지금까지 SSL에 대해 알아보았습니다. 이제 진짜로 연결도 끝냈고 암호화에 쓰일 대칭키를 얻었으니, 다음 편에는 정말 전달하고 싶은 내용을 전달해보겠습니다.
참조
https://www.cloudflare.com/ko-kr/learning/ssl/what-happens-in-a-tls-handshake/
'Computer Science > Network' 카테고리의 다른 글
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 6편 TCP (0) | 2022.08.13 |
---|---|
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 5편 HTTP (0) | 2022.08.10 |
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 3편 Port(포트), Socket(소켓) (0) | 2022.08.10 |
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 2편 DNS (0) | 2022.08.08 |
[네트워크] "www.google.com"을 입력하면 어떻게 되나? 1편 - LAN/WAN, TCP/IP 4 계층, 패킷 교환 방식 (0) | 2022.08.04 |