TLS 에서는 거의 대부분의 모든 통신이 핸드셰이크 과정으로 이루어진다.
핸드셰이크란 데이터 교환이 시작되기 전에 두 당사자 간에 안전한 연결을
설정하는 프로세스를 말한다.
신원을 확인하고 통신 매개변수, 암호화 키를 설정하기 위해 교환되는 일련의
미리 정의된 메시지를 포함한다.
일반적인 예로는 TCP 3방향 핸드셰이크가 있으며, TLS/SSL 과 같은 암호화
프로토콜에서 핸드셰이크는 인증서 확인 및 키 교환을 포함하여 더 복잡하고
다양하게 이루어진다.
핸드셰이크는 안전하고 인증된 통신을 보장하고, 무단 액세스를 방지하며
다양한 네트워크 프로토콜 및 보안 시스템에서 효율적인 데이터 전송을 위한
매개변수를 설정하는 데 있어 필수적인 요소라 볼 수 있다.
본격적인 TLS 핸드셰이크의 과정을 살펴보기 전에,
우리가 사용하는 브라우저 상단 URL에 표시된 인증서 정보를 조회해보면
인증서에 대한 상세정보를 볼 수 있다.
예시로 아래와 같이 표시되어있다고 보자.
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
정체를 알 수 없는 문자열이 나열되어 있다. 하나씩 살펴보도록 하자.
TLS : 인터넷에서 데이터를 암호화하여 안전하게 통신하기 위한 프로토콜
현재 우리는 HTTPS 연결을 사용하고 있으므로 TLS 프로토콜이 사용되는 것을
확인할 수 있다. TLS 프로토콜에 대한 설명
ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) : Diffie-Hellman의 기반인
수학적 연산에 타원 곡선 암호학을 적용한 키 교환 알고리즘으로,
두 통신 주체가 안전하게 대칭키를 공유하도록 한다. 즉, 실제 정보는
대칭키로 암호화 하기 때문에 비대칭키 암호화 알고리즘으로 안전하게
대칭키를 생성한 후 교환한다. 공개키 암호화 과정 / 대칭키 암호화 과정
RSA : 실제 핸드셰이크가 진행되는 부분, 공개키 암호화 과정을 이용한
사용자 인증 및 서명과정에 사용되며, 인증서를 활용하여 사용자를
식별하는 과정을 거친다. RSA의 공개키 서명
AES_128 : 실제 암호화에 사용하는 암호(Cipher)의 종류를 말한다.
대칭키 암호 중에서도 블록 암호, 그 중 DES와 AES 중 하나를 말하며,
지원되는 키의 크기인 128비트, 192비트, 256비트 중 128비트를 사용함이
명시되어 있다. AES 암호에 대해
GCM (Galois/Counter Mode) : 대칭 암호화 알고리즘에 사용되는
운영 모드의 하나로, 암호화 동시에 무결성 검증을 제공하는 특수모드 이다.
SHA256 : 사용자 인증 및 서명, 키를 전달할 때 사용하는 해시함수를 명시.
1. Client Hello
클라이언트는 서버에게 Client Hello
메시지를 보낸다.
이 메시지에는 클라이언트가 지원하는 TLS의 버전 중 가장 최신인 버전,
임의의 숫자와 암호화 알고리즘 집합(Cipher Suite)이 포함되어 있다.
2. Server Hello
TLS의 버전을 선택하는 것은 서버 쪽이다. Server Hello
에는 선택된 TLS 버전,
임의의 숫자와 서버쪽에서 선택한 암호화 알고리즘 집합(Cipher Suite)가 포함되어 있다.
클라이언트가 제시한 TLS의 버전 중 서버쪽에서 지원가능한 버전이 없을 경우
연결 실패 메시지를 보내게 된다.
이후 서버는 클라이언트에게 인증서를 보내게 되는데, 클라이언트에서 이 인증서를
확인하기 위해 공개키를 같이 붙여서 보낸다. Sever Certificate, PK
추가로, 서버는 키 교환을 위한 알고리즘의 매개변수들을 함께 전송한다,
Server Key Exchange
.
마지막으로 서버는 전자 서명을 하여 클라이언트에게 전송한다.
이 내용에는 이전까지 주고받았던 메시지의 내용이 해시함수로 간략화 되어있으며,
서버의 개인키로 서명을 하였기 때문에 클라이언트는 서버의 공개키를 통해
이 내용이 위조되지 않았음을 확인할 수 있고 이후 Server Hello Done
을 보내
이 메시지의 끝을 알린다.
위 과정은 TLS 핸드셰이크에서의 핵심 과정이라고 볼 수 있다.
클라이언트가 연결하고자 하는 서버가 위조되지 않은 실제 그 서버가 맞는지,
공개키 서명을 통한 확인 과정을 거치면서 알 수 있다.
3. Client Key Exchange
클라이언트는 임의로 값을 생성하여 Premaster Secret
을 만든다(보통 48비트).
이 값을 서버의 공개키로 암호화하여 전송한다. 이 값을 받은 서버는 개인키를 통해
복호하고 이렇게 양측이 동일한 프리마스터 시크릿을 공유한다.
이후 프리마스터 시크릿과 이전에 Client Hello
, Server Hello
에서 주고받은
난수를 활용하여 다시 Master Secret
을 만든다.
마지막으로 마스터 시크릿을 기반으로하여 클라이언트와 서버 둘다 동일한 방식으로
Session Key
를 생성한다. 이 세션키에는 앞으로 데이터를 암호화할 대칭키,
데이터 무결성 검증을 위한 MAC키, 암호화 모드에서 사용할 IV를 포함한다.
💡 이러한 과정을 거치는 이유는?
비대칭 암호화는 속도가 느리고 대량의 데이터를 처리하기에 적합하지 않다.
반면에 대칭 암호화는 빠르고 효율적이기 때문에,
공유된 대칭키(세션 키)를 사용하여 통신을 진행함으로써
비대칭 암호화의 보안성과 대칭 암호화의 효율성을 결합한다.
4. Finished Message
클라이언트와 서버가 세션키의 생성까지 되었으면, 클라이언트와 서버는 서로
현재까지 주고받은 내용을 요약하고 그것을 세로 암호화하여 주고받는다.
클라이언트가 먼저 자신이 요약한 정보를 암호화하여 Client Finished
를 보내면,
서버는 이 내용을 세션키로 복호화한 후 자신이 계산한 내용과 비교한다.
반대로 서버 역시 Server Finished
를 통해 동일하게 과정을 수행하여
서로 내용이 위조되지 않았음을 확인하면 핸드셰이크 과정이 성공적으로 마무리 된다.
궁극적으로 우리가 필요로 하였던 것은 무엇이었을까?
바로 클라이언트와 서버만 서로 공유하고있는 비밀
이 필요했다.
이렇게 서로만 알고있는 비밀이 있어야 이를 활용하여 암호화를 하고
정보를 안전하게 주고받을 수 있다.
먼저 통신이 시작되기 전 서로 어떠한 정보를 주고받을 것인지, 어떤 알고리즘, 방법을
사용할 것이고 버전은 무엇을 선택하는지는 Client Hello
, Server Hello
를 통해
알 수 있었다.
이후 클라이언트도 필요하면 확인을 하겠으나, 우리가 접속하는 서버는 그 서버가
위조되지 않았음을 확인해야 한다. Certificate (PK)
, Digital Signature
을 통해
서버의 공개키로 인증서를 확인하고, 개인키로 서명한 것을 공개키로 확인하는
과정을 거쳤다.
서로만의 공유된 비밀을 만들기 위해 사용한
Server Key Exchange
와 Client Key Exchange
는 공유된 비밀을
생성하는 데 있어 필요한 과정이였고 결과적으로 세션 키를 생성하였다.
마지막으로 이 모든 과정이 위조되거나 중간에 공격이 있지 않았음을 입증하기 위해
Client Finished
, Server Finished
를 통해 확인하였다.
현재 TLS 1.0 / 1.1 버전은 더 이상 사용되지 않으며,
1.2와 1.3 버전이 사용되고 있다. 1.3 버전은 1.2 버전보다 더 빠르고 지원하는
암호화가 더 다양하나, 현재로서는 1.2도 강력한 성능을 보여주고 있기에
특별한 경우가 아닌 이상은 1.2를 사용해도 무방하다.
YouTube: TLS Handshake Explained - Computerphile
HTTPS를 위한 SSL/TLS 핸드셰이크 작동원리