TCP는 데이터를 정확히 전달하지만, 그 데이터를 보호하지는 않는다. TCP 위로 흐르는 내용은 평문(plaintext)이라, 같은 네트워크에 있는 누군가가 중간에서 들여다보거나 바꿔치기할 수 있다. 비밀번호를 보내든 결제 정보를 보내든 그대로 노출된다. TLS는 이 문제를 푸는 계층이다. TCP와 그 위의 HTTP 사이에 끼어들어, 흐르는 데이터를 암호화하고 상대가 진짜인지 확인한다. https://, wss://s가 바로 이 TLS다.

TLS는 Transport Layer Security의 약자다. 과거 이름인 SSL(Secure Sockets Layer)로도 불리지만, SSL은 보안 결함으로 오래전 폐기됐고 지금 쓰이는 것은 모두 TLS다. 사람들이 습관적으로 “SSL 인증서"라 부를 뿐이다.

TLS가 보장하는 세 가지

암호화라고 하면 보통 “내용 숨기기"만 떠올리지만, TLS는 세 가지를 함께 보장한다.

기밀성(confidentiality)은 내용을 제3자가 읽지 못하게 하는 것이다. 무결성(integrity)은 전송 중 데이터가 변조되지 않았음을 보장하는 것으로, 누군가 중간에서 한 글자라도 바꾸면 받는 쪽이 알아챈다. 인증(authentication)은 내가 통신하는 상대가 사칭이 아니라 진짜임을 확인하는 것이다. 암호화만 되고 인증이 없다면, 공격자가 중간에서 가짜 서버 행세를 하며 모든 트래픽을 가로채는 중간자 공격(man-in-the-middle)에 무방비가 된다.

두 종류의 암호화

TLS를 이해하려면 암호화 방식이 두 가지라는 것부터 알아야 한다.

대칭키 암호화(symmetric encryption)는 암호화와 복호화에 같은 열쇠를 쓴다. 빠르고 효율적이지만, 양쪽이 같은 열쇠를 공유해야 한다는 문제가 있다. 이 열쇠를 네트워크로 그냥 보내면 도청당하므로, 안전하게 전달할 방법이 따로 필요하다.

비대칭키 암호화(asymmetric encryption)는 한 쌍의 열쇠를 쓴다. 공개키(public key)로 잠근 것은 짝이 되는 개인키(private key)로만 열 수 있고, 그 반대도 성립한다. 공개키는 누구에게나 보여줘도 된다. 비대칭키는 이 열쇠 전달 문제를 풀지만, 계산이 무거워 대량의 데이터를 처리하기에는 느리다.

TLS는 둘을 영리하게 조합한다. 연결 초반에는 비대칭키로 안전하게 대칭키 하나를 합의하고, 그 뒤 실제 데이터는 빠른 대칭키로 주고받는다. 무거운 자물쇠는 열쇠를 건네는 순간에만 쓰고, 일상적인 대화는 가벼운 자물쇠로 하는 셈이다.

핸드셰이크 — 연결을 여는 협상

실제 통신 전에 양쪽이 조건을 맞추는 과정을 핸드셰이크(handshake)라 한다. 큰 흐름은 이렇다. 클라이언트가 자신이 지원하는 암호화 방식 목록을 보내며 인사하면, 서버가 그중 하나를 고르고 자신의 인증서를 함께 보낸다. 클라이언트는 그 인증서를 검증하고, 둘은 이번 세션에서 쓸 대칭키를 안전하게 합의한다. 이 시점부터 모든 통신이 그 대칭키로 암호화된다.

이 협상에는 왕복이 필요하고, 그만큼 지연이 생긴다. 그래서 버전이 올라가며 이 과정을 줄여 왔다. 널리 쓰이던 TLS 1.2는 핸드셰이크에 두 번의 왕복(2-RTT)이 들었지만, 현재 표준인 TLS 1.3은 이를 한 번(1-RTT)으로 줄였고, 한 번 연결했던 서버에는 왕복 없이(0-RTT) 바로 데이터를 보내는 길도 열었다. 앞서 정리한 QUIC이 빠른 것도 TLS 1.3을 전송 과정에 통합했기 때문이다.

인증서와 신뢰 사슬

서버가 보낸 공개키가 정말 그 서버의 것인지는 어떻게 믿을까. 여기서 인증서(certificate)가 등장한다. 인증서는 “이 공개키는 이 도메인의 것이 맞다"는 사실을 보증하는 문서이고, 그 보증을 인증 기관(CA, Certificate Authority)이라는 신뢰받는 제3자가 서명해 준다.

브라우저와 운영체제에는 신뢰하는 CA들의 목록이 미리 내장돼 있다. 서버 인증서를 검증할 때, 브라우저는 그 인증서에 서명한 CA를 따라 올라가 내장된 신뢰 목록에 닿는지 확인한다. 이 연결 고리를 신뢰 사슬(chain of trust)이라 한다. 사슬이 끊기거나, 도메인이 인증서와 안 맞거나, 유효기간이 지났으면 브라우저는 경고를 띄운다.

개발 중에 자체 서명 인증서(self-signed certificate)를 쓰면 이 경고를 만난다. 어떤 CA도 보증하지 않은, 자기가 자기를 보증한 인증서이기 때문이다. 암호화 자체는 동작하지만 인증 사슬이 없어 신뢰되지 않는다. 그래서 로컬에서 wss://로 붙으려면 그 인증서를 브라우저 신뢰 목록에 직접 등록하거나 별도 프록시를 거치게 된다.

어디에 얹히나

TLS는 특정 프로토콜에 묶이지 않고 TCP 위라면 어디든 끼어든다. HTTP에 얹히면 HTTPS가 되고, WebSocket에 얹히면 wss://가 되며, 메일 프로토콜에도 적용된다. QUIC처럼 TLS를 아예 내부에 통합한 경우도 있다. 공통점은 “기존 프로토콜은 그대로 두고, 그 아래에서 암호화 계층만 추가한다"는 것이다.

이점과 트레이드오프

이점은 분명하다. 도청과 변조와 사칭을 한꺼번에 막아주고, 기존 프로토콜을 거의 바꾸지 않고도 보안을 입힐 수 있다. 오늘날 평문 통신은 사실상 표준 미달로 취급된다.

대가는 비용이다. 핸드셰이크에 왕복이 더해져 첫 연결이 느려지고(TLS 1.3과 세션 재개로 많이 줄긴 했다), 암호화·복호화에 약간의 연산이 든다. 인증서는 발급받고 갱신해야 하며, 만료된 인증서를 방치하면 서비스가 통째로 막힌다. 그럼에도 이 비용은 보안의 대가로 받아들이는 것이 현재의 기본값이고, 무료 자동 갱신 인증서가 보급되며 운영 부담도 크게 낮아졌다.