고대 그리스에서는 타인에게 노출되지 않아야 하는 중요한 정보를 보낼 때, 전달하는 사람(사자)의 머리를 밀고 중요한 정보를 적은 뒤 머리가 자라 글이 보이지 않으면 상대방에게 사자를 보냈다고 한다. 그렇게 되면 해당 사실을 모르는 사람은 정보를 알 수 없고, 사실을 아는 수신자는 다시 머리를 깎은 후 정보를 볼 수 있을 것이다. 이 암호 기법을 스테가노그래피라고 한다.

정보를 전달하기 위해서는 머리가 자라는 동안 기다려야 한다는 단점이 있지만, 중요한 정보를 확실히 감추는 데에는 이만한 방법이 없다. 옛날부터 중요한 정보를 안전하게 보내는 것은 매우 중요했다는 것을 알 수 있다.
HTTPS 통신 과정에서도 송신자와 수신자는 주고받을 데이터를 안전하게 보내는 것을 중요시 한다. 이때문에 데이터를 암호화할 대칭키(비밀키)를 타인에게 노출시키지 않고 클라이언트가 서버에게 전송하기 위해 협상을 벌인다.
오늘 다룰 TLS & SSL Handshake는 송신자와 수신자가 암호화된 데이터를 교환하기 위해 벌이는 일련의 협상이다. 협상 과정에서는 TLS 인증서 전달, 대칭키(비밀키) 전달, 암호화 알고리즘 결정, TLS/SSL 프로토콜 결정 등이 포함된다.

위의 파란색 칸은 TCP layer의 3-Way Handshake로 HTTPS가 TCP 기반의 프로토콜이기 때문에 암호화 협상(TLS Handshake)에 앞서 연결을 생성하기 위해 실시하는 과정이고, 아래 노란색 상자의 패킷들이 TLS Handshake이다.
아래 두 가지를 기억하면서 글을 살펴보자.
- 암호화 알고리즘(Cipher Suite) 결정
- 데이터를 암호화할 대칭키(비밀키) 전달
클라이언트가 서버에 연결을 시도하며 전송하는 패킷이다. 자신이 사용 가능한 Cipher Suite 목록, Session ID, SSL Protocol Version, Random byte 등을 전달한다.

🔼 Client Hello Packet
Cipher Suite는 TLS 통신에서 보안 연결을 설정하는 데 사용되는 알고리즘의 집합이다. 이는 TLS의 프로토콜 버전, 인증서 검증 방식, 데이터 암호화 프로토콜, 해시 알고리즘 등의 정보를 포함한다. 클라이언트는 서버에 자신이 지원하는 Cipher Suite 목록을 제공하고, 서버는 그 중 하나를 선택해 통신에 사용할 암호화 알고리즘을 결정한다. 이렇게 선택된 Cipher Suite에 따라 이후의 데이터가 암호화된다.

🔼 Cipher Suite의 구성
서버는 클라이언트가 보낸 Client Hello 패킷에서 제공된 여러 Cipher Suite 중 하나를 선택한다. 서버는 선택한 Cipher Suite와 함께 자신이 사용할 TLS 프로토콜 버전 등의 정보를 포함한 Server Hello 패킷을 클라이언트에 보낸다.

🔼 Server Hello Packet
위 사진을 보면 Client Hello에서 17개였던 Cipher Suite와 달리, 아래에서는 서버가 선택한 한 줄(Cipher Suite: TLS_AES_256_GCM_SHA384)만이 존재하는 것을 알 수 있다. 클라이언트가 보낸 리스트에 있는 Cipher Suite 중 한 개를 선택한 것이다.
서버는 클라이언트가 보낸 Cipher Suite 리스트 중 자신이 지원하는 가장 높은 등급의 Suite를 선택하여 안전한 통신을 시작한다.
서버가 자신의 TLS 인증서를 클라이언트에게 전달한다. 나의 경우 TLS1.3이기 때문에 key 교환 후 Application Data Protocol을 통해 Certificate이 암호화되어 전송되기 때문에 보이지 않는다. TLS1.2를 사용한 모 블로그의 사진으로 대체하겠다.

🔼 Certificate Packet
이 인증서에는 서버가 발행한 공개키가 포함되어 있으며, 서버는 개인키를 소유한다. 클라이언트는 CA의 공개키를 이용해 인증서를 검증하고, 이 인증서가 유효한지 확인한다.
위 사진을 보면 인증서가 어떤 알고리즘(RSA)으로 암호화되었고, 어떤 Hash 알고리즘(SHA256)으로 서명되었는지 확인 가능하다.
Server Key Exchange는 서버의 공개키가 TLS 인증서에 포함되지 않았을 때 서버가 직접 공개키를 전달하는 과정이다. 만약 인증서에 공개키가 포함되어 있다면, 클라이언트는 CA의 공개키로 인증서를 복호화해 서버의 공개키를 얻으므로 이 단계가 생략된다.

이 경우 키 교환 알고리즘이 Diffie-Hellman이 사용되어, 서버는 키 교환을 위한 추가 정보를 제공해야 하므로 Server Key Exchange가 발생한다. 이 과정을 통해 최종 세션키가 생성된다.
클라이언트는 대칭키를 생성한 후, 서버 인증서에서 추출한 서버의 공개키로 해당 대칭키를 암호화하여 서버로 전달한다. 이 대칭키는 이후 실제 데이터 암호화에 사용되며, TLS Handshake의 가장 중요한 목적 중 하나이다.

위의 사진처럼 Diffie-Hellman과 ECDHE 알고리즘을 사용하면 클라이언트는 대칭키를 직접 보내는 대신, 대칭키를 만들기 위한 재료(키 생성 파라미터)를 서버와 교환한다. 이를 통해 서버와 클라이언트는 각각 교환한 재료를 조합해 같은 대칭키를 생성하게 된다.
반면 RSA 알고이름을 사용할 경우, 클라이언트가 이미 생성한 대칭키를 서버의 공개키로 암호화하여 서버에 전달한다. 최종적으로 이 대칭키를 이용해 실제 데이터가 암호화된다.
Change Cipher Spec은 클라이언트와 서버가 암호화를 시작하겠다는 신호로, 이 메세지를 주고받은 후 모든 통신이 암호화된다. 즉, 양측이 합의한 암호화 방식을 적용하는 단계이다.
Finished는 Handshake가 끝나고, 성공적으로 암호화 키 교환과 인증이 완료되었음을 확인하는 메세지이다. 이 메세지에는 Handshake 과정 전반의 무결성을 확인하는 해시 값이 포함된다.

📌 TLS Handshake 요약
Client Hello(암호화 알고리즘 나열 및 전달) → Server Hello(암호화 알고리즘 선택) → Server Certificate(인증서 전달) → Client Key Exchange(데이터를 암호화할 대칭키 전달) → Client / Server Hello done(정보 전달 완료) → Finished(TLS Handshake 종료)
위 과정을 통해 클라이언트와 서버는 데이터를 암호화할 동일한 대칭키를 갖게 되며, 서로에게 각자 갖고 있는 동일한 대칭키를 이용하여 데이터를 암호화해 전송하거나 복호화한다. 클라이언트와 서버는 이제 성공적으로 비밀 친구가 된 것이다.
Reference