secure한 HTTP
이 protocol로 만들어진 connection 내의 data transfer들은 전부 encrypted되어 있다.
이때 encryption에 사용하는 protocol이... 옛날에는 SSL이었으나 지금은 TLS다. TLS은 SSL이랑 거의 차이점이 없다. protocol 주관하는 곳이 바꿔진게 가장 큰 특징이다. 다만 어쨌든 현재 HTTPS에서 사용하고 있는건 TLS고 TLS가 SSL보다 최신인 protocol로 취급 받고 있다.
handshake를 통해 authentication을 해 device끼리 서로 connection을 통해 연결된 상대방이 '진짜' 그 상대방인지를 판단할 수 있다.
connection이 구축되면 data가 connection을 통해 전달 되는 과정에 malicious agent에 의해 변조되지 않도록 보장하는 data integrity도 지원을 해준다.
connection이 구축되면 connection 상의 data를 malicious agent가 읽어도 무슨 내용물인지 이해할 수 없도록 encrypt한다. 서로는 encrypt 된 data가 뭔지 이해 할 수 있다. 즉 confidentiality 지원.
밑은 TLS 1.3 이후에 의무화된 내용이다. 이전 버전들에서도 이걸 사용하는건 가능하지만, 이후 설명할 RSA 기반 encryption도 선택할 수 있도록 해준다. 그게 보안상 문제가 있어가지고 지금 방식이 의무화가 됨. 밑에 소개하는 방식은 ephemeral diffie-hellman key exchange라고도 불린다.
먼저 connection을 구축하려는 device들끼리 먼저 일반적인 TCP handshake를 통해 TCP connection을 구축한다.
이후 위에 말한 TLS handshake가 발생하게 된다.
먼저 client가 ClientHello message를 보낸다. 여기에는 본인이 사용하는 TLS 버전과 본인이 encryption에 사용할 수 있는 알고리즘, 그리고 client가 만든 랜덤 byte들로 이루어진 string을 보낸다.
이후 server이 ServerHello message를 보낸다. 여기에는 server의 TLS certificate, server의 public key, server이 사용할 encryption algorithm, server측에서 만든 랜덤 byte들로 이루어진 string, server의 Diffie-Hellman paramter, 그리고 앞의 내용물에 대한 digital signature을 생성해가지고 client에게 전달한다. digital signature은 server의 private key로 만들어진다. server의 Diffie-Hellman parameter은 미리 약속된 generator, prime과 본인의 private key를 가지고 만들어진다.
client는 저것들을 받으면 일단 digital signature을 같이 전달된 server의 public key로 해독후 내용물이 일치하는지를 확인한다. 맞으면 이 certificate를 부여한 CA가 본인이 신뢰하는 CA인지를 파악한다.
맞다고 가정해보자. 이때 server의 public key와 server의 domain detail을 합한 값을 CSR이라고 해보자.
certificate에는 CSR과 CSR의 hash가 CA의 private key로 encrypt된 값이 concatenate된 채로 존재해야 한다. client가 certifcate를 parse해가지고 encrypt된 값과 encrypt되지 않은 CSR의 hash값이 같으면, 증명서가 유효하고 실제로 이를 보낸 측이 본인이 연결하려던 server임을 authenticate할 수 있게 된다.
client가 직접 CSR을 hashing할 수 있으며, private key로 encrypt된 값은 CA에서 제공하는 CA의 public key를 가지고 decrypt한다. 그리고 값을 비교. 일치하면 client는 server이 본인이 연결하려던 그 server이 맞음을 확신하게 된다.
client는 본인의 Diffie-Hellman parameter을 server에게 전달한다. ephemeral Diffie-Hellman key exchange에서 사용되는 parameter인데 미리 약속된 generator, prime과 본인의 private key를 가지고 만들어진다.
서로 상대측에서 전달한 Diffie-Hellman parameter에 본인들의 private key를 적용해가지고 공통된 premaster key를 obtain하게 된다. 왜 둘이 공통된 premaster key를 가지고 이것이 보안상 문제가 없는 원리가 궁금하면 다음 2개 링크 참고
What's the purpose of DH Parameters? - StackExchange InformationSecurity
Diffie-Hellman key exchange - Wikipedia
이후 앞에서 각자가 만들었던, 교환된 random number들과 이 premaster key를 가지고 session key들을 만든다.
이후 client가 server에게 finished message를 session key로 encrypt해서 전달한다.
server이 이를 decrypt한 후 client에게 finished message를 session key로 encrypt해서 전달한다. 이러면 Ephemeral Diffie-Hellman 기반 TLS handshake가 끝난다.
참고로 생성되는 session key pair은 2개로, 하나가 confidentiality, 즉 encryption 용도고 또 다른게 integrity 용도다. 그래서 data integrity, authentication, confidentiality를 전부 보장하는 protocol이 완성 될 수 있는 것이다.
만약 우리가 HTTPS를 지원하는 server을 만들고 싶다면, 일단 HTTP를 구현해 놓으면 된다.
이후 ceritificate를 CA로부터 받아야 하는데, 이 때 비용이 발생할 수 있다. cloudflare같은 기업에서는 유효한 CA를 그냥 웹사이트 운영진들에게 제공해주기도 한다.
session key를 만드는 방법은 여전히 동일하게, 서로 전달된 두개의 random number과 이 premaster key를 가지고 생성한다.
이게 보안상 문제가 있는 이유는 forward secrecy (혹은 perfect forward secrecy)가 보장이 되지 않아서다. forward secrecy는 session key 생성 과정에 이용된 private key 중 하나가 compromise되거나 애초에 communication에 참여했던 두 device들의 private key가 유출이 되더라도 '과거의' 내용물을 이해하지 못하는 것을 보장한다. 참고로 masquerading을 막지는 못한다는 점 유의
RSA 기반의 경우 server의 private key가 유출이 되는 순간 (session별로 client가 server에게 보낸 encrypt된 premaster key message들을 보유하고 있을 경우) server과 class간의 이전 메세지들을 모두 decrypt 할 수 있기 때문에 문제가 되는 것이다. 그래서 TLS 1.3부터 RSA 기반 key exchange를 아예 못하도록 막았다.
참고자료
SSL, TLS, HTTPS Explained - ByteByteGo
What is HTTPS? - cloudflare
What is SSL? | SSL definition - cloudflare
What happens in a TLS handshake? | SSL Handshake - cloudflare
How does the client verify servers certifcate in SSL? - StackOverflow
How does keyless SSL work? - cloudflare
A simple misunderstanding of SSL/TLS - StackExchange Cryptography
Forward Secrecy - Wikipedia