HTTPS는 왜 빨라졌나: TLS 1.3 핸드셰이크와 0-RTT 세션 재개

🤖 AI Summary
HTTPS로 접속할 때마다 브라우저와 서버는 암호화 방식을 협상하는 핸드셰이크를 먼저 거칩니다. 이 협상이 왕복을 여러 번 하면 그만큼 첫 화면이 늦게 뜨죠. TLS 1.3은 이 핸드셰이크를 한 번의 왕복(1-RTT)으로 줄였습니다. 여기에 더해 한 번 맺은 연결을 기억해 두는 세션 재개가 있습니다. RFC 8446 기준 TLS 1.3은 세션 재개를 사전 공유 키(PSK)로 통합했고, 서버가 발급한 티켓을 다시 제시하면 핸드셰이크가 짧아져요. 한 걸음 더 나가면 재접속 때 첫 메시지에 데이터를 실어 보내는 0-RTT도 가능합니다. 다만 0-RTT 데이터는 더 약한 보장을 가지고 리플레이 공격에 노출될 수 있어, 두 번 실행되면 안 되는 요청에는 쓰지 않는 것이 안전합니다. 근거는 RFC 8446과 MDN입니다.
블로그 목차
접속마다 반복되는 인사: 핸드셰이크가 만드는 지연
HTTPS 주소로 사이트에 들어갈 때, 데이터가 오가기 전에 보이지 않는 준비 절차가 먼저 일어납니다. 브라우저와 서버가 어떤 암호를 쓸지 정하고 열쇠를 교환하는 TLS 핸드셰이크예요. 문제는 이 인사에도 시간이 든다는 점입니다. 브라우저가 메시지를 보내고 서버의 답을 기다리는 왕복(RTT)이 쌓일수록 첫 응답이 그만큼 밀리죠.
이전 세대인 TLS 1.2는 이 협상에 보통 두 번의 왕복(2-RTT)이 필요했습니다. 멀리 있는 서버일수록 왕복 한 번의 비용이 커서, 핸드셰이크만으로 눈에 띄는 지연이 생겼어요. TLS 1.3은 바로 이 지점을 손봤습니다. 협상 과정을 재설계해 핵심 절차를 한 번의 왕복으로 끝내고, 재접속은 더 짧게 만드는 방향으로 바꾼 것이죠. 지금부터 그 원리를 RFC 8446 기준으로 살펴봅니다.
TLS 1.3의 1-RTT 핸드셰이크
RFC 8446은 TLS 1.3 핸드셰이크를 세 단계로 설명합니다. 첫째 키 교환(Key Exchange) 단계에서 공유할 키 재료를 정하고 암호 파라미터를 고르는데, RFC의 표현으로 "이 단계 이후의 모든 것은 암호화"됩니다. 둘째 서버 파라미터 단계에서 부가 설정을 주고받고, 셋째 인증 단계에서 서로를 확인하죠. 핵심은 이 과정이 한 번의 왕복(1-RTT) 안에 이뤄지도록 짜였다는 점입니다.
흐름을 단순화하면 이렇습니다. 클라이언트가 첫 메시지에 자신이 지원하는 방식과 키 교환 정보를 함께 담아 보내면, 서버가 한 번의 응답으로 선택을 확정하고 인증까지 진행합니다. 브라우저는 그 답을 받은 직후부터 애플리케이션 데이터를 보낼 수 있어요. TLS 1.2가 협상 뒤에 다시 한 번 왕복을 기다렸던 것과 달리, TLS 1.3은 그 한 박자를 없앤 셈이죠. 연결을 미리 맺어 두는 방법과 함께 쓰면 지연은 더 줄어드는데, 브라우저 힌트로 연결을 예열하는 방법은 리소스 힌트 글에서 다뤘습니다.

두 번째 접속은 더 빠르게: 세션 재개와 PSK
같은 사이트를 다시 방문할 때마다 처음부터 협상을 반복하면 아깝습니다. 그래서 TLS에는 한 번 맺은 연결 정보를 재사용하는 세션 재개가 있어요. RFC 8446은 TLS 1.3에서 기존 세션 재개 기능이 사전 공유 키(PSK)와 통합됐다고 설명합니다. 이전처럼 별도의 재개 방식을 두는 대신, 재접속을 PSK라는 하나의 틀로 다루게 된 것이죠.
동작은 이렇습니다. 첫 접속의 핸드셰이크가 끝나면 서버가 NewSessionTicket 메시지로 티켓을 하나 발급합니다. 클라이언트는 이 티켓을 보관해 뒀다가, 다음에 접속할 때 다시 제시하죠. 서버는 티켓으로 이전 연결을 알아보고 핸드셰이크를 짧게 처리합니다. 매번 처음부터 인증을 되풀이하지 않아도 되니, 재접속의 준비 시간이 줄어드는 셈이에요. CDN을 쓰면 사용자와 가까운 엣지가 TLS를 종단하고 이 세션 정보를 관리해, 왕복 거리 자체가 짧아지는 이점도 있습니다.
왕복 0회의 유혹과 대가: 0-RTT early data
세션 재개를 한 걸음 더 밀어붙인 것이 0-RTT입니다. RFC 8446 기준, 클라이언트와 서버가 PSK를 공유한 상태라면 클라이언트는 핸드셰이크 첫 메시지에 데이터를 함께 실어 보낼 수 있습니다. 이를 early data라고 부르는데, 서버의 응답을 기다리지 않고 요청을 먼저 보내니 왕복이 사실상 0회가 되죠. 재방문이 잦은 서비스에서는 체감 속도가 빨라집니다.
다만 공짜는 아닙니다. RFC 8446은 0-RTT 데이터가 ServerHello에 의존하지 않아 더 약한 보장을 가진다고 못 박습니다. 특히 리플레이 공격에 취약해서, 공격자가 0-RTT 데이터를 그대로 복제해 다시 보내는 위협이 있다고 부록에서 설명하죠. 그래서 0-RTT는 두 번 처리돼도 안전한 멱등한 요청에만 쓰는 것이 원칙입니다. 결제나 상태를 바꾸는 요청은 0-RTT로 보내지 않고 일반 핸드셰이크를 거치는 편이 안전해요. 속도와 안전 사이에서 어디에 0-RTT를 열지 신중히 골라야 하는 이유입니다.

이것만 기억하세요
TLS 1.3은 HTTPS 핸드셰이크를 1-RTT로 줄여 접속 지연을 낮췄습니다(RFC 8446). 재접속은 세션 재개로 더 빠른데, TLS 1.3은 이를 사전 공유 키(PSK)로 통합하고 서버가 NewSessionTicket으로 발급한 티켓을 재사용합니다. 한 걸음 더 나간 0-RTT는 첫 메시지에 데이터를 실어 왕복을 0회로 만들지만, 약한 보장과 리플레이 위험 때문에 두 번 처리돼도 안전한 멱등 요청에만 써야 합니다.
자주 묻는 질문 (FAQ)
Q. TLS 1.3 핸드셰이크는 왜 더 빠른가요?
왕복 횟수가 줄었기 때문입니다. 이전 방식이 협상에 두 번의 왕복(2-RTT)을 쓰던 것을, RFC 8446 기준 TLS 1.3은 핵심 협상을 한 번의 왕복(1-RTT)으로 마치도록 재설계했습니다. 키 교환 단계 이후의 메시지는 곧바로 암호화되어 오가므로 접속 지연이 줄어듭니다.
Q. 세션 재개가 무엇인가요?
한 번 맺은 연결의 정보를 재사용해 다음 접속을 빠르게 하는 기능입니다. RFC 8446 기준 TLS 1.3은 기존 세션 재개를 사전 공유 키(PSK)로 통합했고, 서버가 NewSessionTicket으로 발급한 티켓을 클라이언트가 보관했다가 재접속 때 제시해 핸드셰이크를 짧게 만듭니다.
Q. 0-RTT는 무엇이고 왜 주의해야 하나요?
PSK를 공유한 상태에서 클라이언트가 핸드셰이크 첫 메시지에 데이터를 함께 보내는 방식(early data)입니다. 왕복을 기다리지 않아 빠르지만, RFC 8446은 0-RTT 데이터가 ServerHello에 의존하지 않아 더 약한 보장을 가지며 리플레이 공격에 노출될 수 있다고 경고합니다.
Q. 0-RTT를 아무 요청에나 써도 되나요?
아닙니다. 리플레이 위험 때문에, 같은 요청이 두 번 처리돼도 문제없는 멱등한 요청에만 쓰는 것이 안전합니다. 결제나 상태를 바꾸는 요청처럼 두 번 실행되면 안 되는 작업에는 0-RTT를 피하고 일반 핸드셰이크를 거치는 편이 낫습니다.
Q. CDN은 TLS 핸드셰이크에 어떤 도움이 되나요?
CDN은 사용자와 가까운 엣지에서 TLS를 종단합니다. 핸드셰이크를 먼 원본 서버가 아니라 가까운 엣지와 주고받으므로 왕복 시간이 짧아지고, 엣지가 세션 재개 정보를 관리해 재접속도 빨라집니다. 접속 지연을 줄이는 데 도움이 됩니다.



