TLS1.3 핸드쉐이크를 살펴보자.
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 으로 표기된다.
또한 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 설정을 해두어야 한다.
설정하는 방법에 대해서는 앞선 포스팅에서 설명했으므로 참고
'NETWORK Security > 보안 프로토콜' 카테고리의 다른 글
TLS1.3 (7) - Tool (0) | 2020.12.31 |
---|---|
TLS1.3 (6) - 환경 구축 (Nginx-2) (0) | 2020.12.29 |
TLS1.3 (5) - 환경 구축 (Nginx-1) / nginx, openssl RPM update (0) | 2020.12.29 |
TLS1.3 (4) - 환경 구축 (Apache) (0) | 2020.12.29 |
TLS1.3 (3) - TLS1.3 과 기존 TLS 차이점 (0) | 2020.12.29 |