본문 바로가기

NETWORK Security/보안 프로토콜

TLS1.3 (8) - TLS1.3 Handshake / 1-RTT&0-RTT / 완전 협상&단축 협상

 

TLS1.3 핸드쉐이크를 살펴보자.


 

 

TLS1.3  Handshake

 

 

TLS 1.3 1-RTT (완전 협상)

 

 

 

 

 

 

                  client -------------------------------------------------------- server

Client Hello -> 

                                                                       <- Server Hello, Change Cipher Spec, Encrypted Extensions, Finished

Change Cipher Spec, Finished ->

 

 

 


 

 

 

 

구축을 마친 후 패킷을 잡아 구체적인 핸드셰이크 과정을 보면, 과정이 간소화 된 것을 확인할 수 있다. 

TLS1.3 에서는 cipher suites 선택 방법을 최대한 단순화 시켰는데,

 

 

[[[ Client Hello ]]] client random, supported_version, key_share, psk_key_exchange_modes, pre_shared_key

 

서버가 한번에 조합되어 있는 cipher suites 에서 하나를 선택하여 다시 클라이언트에게 보내고 통신해야하는 TLS1.2와 달리

TLS1.3 에서는 cipher suites 의 각 부분 (암호화 알고리즘, 키 교환 알고리즘, 인증 알고리즘)을 각각 합의하여 구현체의 부담을 덜고, 라운드 트림을 단축한다.

 

키 교환 알고리즘에서 RSA 가 배제되어 옵션이 매우 축소된 클라이언트는 시작부터 D-H를 사용한다고 가정할 수 있기 때문에,(물론 D-H도 x25519 등의 여러 방식이 존재하지만 이전보다 추측이 쉬워진 것)암호화 및 키 교환 방식 모두에서 줄어든 경우의 수를 Client Hello 에서 한번에 전송한다. 이게 바로 key_share 에 해당한다.

 

 

 

클라이언트의 psk_key_exchange_modes 확장 필드는, 이 필드 내 적힌 모드에서만 psk 사용을 지원한다는 의미로,클라이언트가 pre_shared_key 필드를 psk 키 협상을 위해 전송할 경우, 이 확장 필드도 반드시 같이 제공해야한다.

 

만약 psk_key_exchange_modes 없이 pre_share_key 만 제공된다면, 

서버는 클라이언트가 나열하지 않은 키 교환 모드를 선택하게 되기 때문에 핸드셰이크를 중단한다.

 

 

 

 

 

[[[ Server Hello ]]]

sessionID, server random, supported_version, key_share, pre_shared_key

 

TLS1.3 의 핸드셰이크는 키 하나를 만들어서 공유하는데, 이 키가 바로 PSK(pre-shared key)이며, 세션 재 연결 시 라운드 트립을 줄이기 위해 사용한다.

(TLS1.3 단축 협상 0-RTT)

 

만일 서버가 psk를 통해 인증 과정을 대체한다면, 인증서 또는 인증 확인 메시지를 같이 보내지 않아도 되며

혹여나 서버가 클라이언트의 psk 재시작을 거부했을 시,

전체 핸드셰이크로 다시 복귀할 수 있도록 클라이언트는 세션 재 연결 시에도 key_share 를 서버에 함께 전송한다.

이렇게 서버가 psk 키 설정에 협상을 하기 위해 보내는 것이 pre_share_key 메시지이다.

 

 

 

 

 

 

그리고 상호간 Change Cipher Spec (협상 내용 적용)을 주고 받으며 핸드셰이크 합의를 완료하여  바로 finished 를 보낸다.

즉, TLS1.2 에서의 premaster secret 생성 과정, cipher suites 선택 등을 모두 대체해 전체 라운드 트립을 단축할 수 있게 되는 것이다.

 

 

 

 

 

 


 

 

 

 

TLS 1.3 1-RTT (완전 협상)

자세히 뜯어보면 Client Hello 에서,

버전 협상을 잘못 구현한 기존 서버와의 호환성을 위해 TLS1.3 하위 버전이 Handshake Protocol Version 으로 표기된다.

 

 

 

 

 

 

RFC 8446

또한 TLS1.3은 16진수 0x0304로 표기되며, suppoerd_versions 필드에 지원 가능한 모든 TLS 버전이 표기되며

우선 순위대로 나열되고, 우선 순위에 따라 맨 위부터 협상을 시도하고 상호 지원 가능하다면 그 버전으로 핸드셰이크를 수행한다.

 

클라이언트나 서버 둘 중 하나가 TLS1.3 호환이 되지 않을 경우, 둘이 호환이 가능한 최상위 버전으로 핸드셰이크를 수행한다.

 

 

 

 

 

 


 

 

 

TLS 1.3 0-RTT (단축 협상)

 

 

 

 

 

그리고 앞에서 간단히 설명했듯, 세션 재개 시 0-RTT (zero-Round Trip Time)를 지원한다. (단축 협상)

 

첫 TLS Handshake 완료 후 서버와 클라이언트에 공유된 암호 키 (psk)를 로컬에 저장하면,

클라이언트는 이 키를 사용하여 첫 번째 요청에서 바로 http를 포함하여 서버로 전송한다.

 

 

 

1-RTT 와 Handshake 과정에서 보이는 차이는 Client Hello내 확장 필드로 존재하는 early_data 의 유무이다.

0-RTT 의 경우 early_data 필드가 존재한다.

 

 

0-RTT를 통해 암호화 연결 속도를 향상시킬 수 있고, 리소스 절약이 가능하다는 장점이 있다.

 

그러나 보안적인 측면에서는 허점이 될 수 있는데, 예를 들어 replay-attack이 가능한 취약점이 될 수 있다.

공격자가 0-RTT 연결 재시작이 되었을 때의 요청을 가로챌 수 있다면, 암호화에 사용된 개인키  등을 알 수 없으므로

내용을 해독해서 사용자 정보를 얻을 수는 없지만 동일 요청을 반복적으로 재현하는 등의 공격이 가능해진다. (계좌에서 인출 반복 등)

 

0-RTT는 보안을 위한 옵션이 아니라는 뜻이다.

그래서인지 TLS1.3 을 지원하는 웹 서버에서 0-RTT 설정은 디폴트 값이 off 이므로,

0-RTT 사용을 반드시 해야하는 환경에서는 별도로 on 설정을 해두어야 한다.

 

설정하는 방법에 대해서는 앞선 포스팅에서 설명했으므로 참고

 

 

 

 

참고 : b.luavis.kr/server/tls-1.3