https의 자물쇠 뒤에는 이상한 문제가 하나 숨어 있습니다.
암호로 잠그려면 열쇠를 나눠 가져야 하는데, 열쇠를 보내는 길 자체가 도청당하고 있다면?
TLS의 답은 기발합니다 — 비밀을 보내지 않고, 양쪽이 같은 열쇠 재료를 각자 계산합니다. 이 데모는 그 과정 하나만 보여줍니다.
열쇠를 보내지 않고 나눠 갖는 방법
양쪽은 비밀 조각(a, b)을 집에 두고, 공개 조각(A, B)만 교환합니다.
- 내 컴퓨터: 비밀 a + 공개 B → 공유 비밀 계산
- 서버: 비밀 b + 공개 A → 같은 공유 비밀 계산
- 도청자: 공개 A + 공개 B → 아무것도 안 나옴 ❌
비밀과 완성된 열쇠는 회선을 지나가지 않습니다. 실제 TLS 1.3은 이 공유 비밀에서 HKDF로 방향과 용도별 여러 트래픽 키를 만듭니다. 데모는 디피-헬만 키 교환과 키 유도 과정을 하나의 "열쇠 재료" 비유로 줄였습니다.
신분증도 확인합니다
가짜 서버와 완벽하게 암호화된 대화를 해봤자 소용없습니다. 그래서 내 컴퓨터는 신뢰할 수 있는 인증서 사슬, 접속한 호스트 이름과 유효 기간을 확인합니다. 서버의 CertificateVerify 서명으로 인증서 개인키의 실제 소유도 검증하고, 양쪽의 Finished 확인값까지 맞아야 핸드셰이크가 끝납니다.
이 과정은 TCP 연결이 만들어진 직후 진행됩니다. 걸리는 시간은 네트워크 왕복 시간과 인증서 검증 환경에 따라 달라집니다.
도청자 칸을 보며 따라가 보세요
매 장면의 도청자 칸만 보세요
공개 조각만 보고도 안전한 이유
- 1내 공개 조각
- 2서버 공개 조각
- 3같은 열쇠
- 4서버 확인
- 5연결 완료
- 6암호문 전송
아래 ‘보안 연결 시작’을 누르고, 매 장면의 도청자 칸을 함께 확인해 보세요.
비밀 세 가지만
도청자가 비밀과 평문을 얻지 못한 이유
공개 조각만 교환하고 공유 비밀은 각자 계산해요. 공개 조각을 전부 지켜봐도 비밀 조각 없이는 같은 값을 계산할 수 없어요.
인증서 사슬과 호스트 이름을 확인하고, CertificateVerify 서명으로 서버가 인증서의 개인키를 실제로 갖고 있는지도 확인해요.
연결이 완성되면 TLS 안의 비밀번호나 카드 번호는 잠긴 채로 이동해요. 다만 IP 주소, 통신 시각과 크기 같은 정보까지 숨기는 것은 아니에요.
데모만 따로 보려면 전체 화면으로 열기.
- 보안 연결 시작을 누르고, 여섯 장면의 제목만 따라갑니다.
- 각 장면에서 도청자 칸에 무엇이 보이는지 확인합니다.
- 자세한 숫자가 궁금할 때만 교환한 기술 값 보기를 펼칩니다.
- 자물쇠가 잠긴 뒤 진짜 데이터가 암호문으로 지나가는 것을 봅니다.
자물쇠가 안 잠길 때 읽는 법
브라우저의 TLS 오류 화면은 무섭게 생겼지만, 실제로 자주 나오는 원인은 몇 가지로 정해져 있습니다. 앞의 두 단계 중 어디서 걸렸는지로 나누면 읽기 쉽습니다.
- 이름이 안 맞음 — 인증서에 적힌 도메인과 실제 접속한 주소가 다릅니다.
www를 붙였는지 여부나, 인증서를 발급받지 않은 하위 도메인에서 흔합니다. - 기간이 지남 — 자동 갱신이 조용히 멈춘 경우입니다. 서버는 잘 도는데 어느 날 갑자기 전체 접속이 막히는 전형적인 모습입니다.
- 중간 인증서 누락 — 사슬의 가운데 고리를 서버가 함께 보내지 않은 경우입니다. 브라우저에서는 되는데 다른 도구나 서버 간 호출에서만 실패하는, 가장 헷갈리는 형태로 나타납니다.
세 번째가 특히 성가신 이유는 어떤 클라이언트는 성공하기 때문입니다. 일부 브라우저는 빠진 고리를 알아서 찾아 보완하지만, 그렇지 않은 도구는 그대로 실패합니다.
직접 확인하기
서버가 실제로 무엇을 보내는지는 명령 하나로 볼 수 있습니다.
# 인증서 사슬과 협상된 TLS 버전 확인
openssl s_client -connect example.com:443 -servername example.com </dev/null
# 유효 기간만 빠르게 확인
openssl s_client -connect example.com:443 -servername example.com </dev/null 2>/dev/null \
| openssl x509 -noout -dates -subject
출력의 Certificate chain에 서버 인증서만 있고 중간 인증서가 없다면 위의 세 번째
경우입니다. Verify return code: 0 (ok)가 나오면 검증까지 통과한 것입니다.
-servername을 빼면 다른 인증서가 돌아올 수 있는데, 한 IP가 여러 도메인을 서비스할
때 어떤 인증서를 줄지 이 이름으로 고르기 때문입니다.
1.3은 정확히 왕복 한 번을 아낍니다
TLS 1.3의 핸드셰이크는 왕복 한 번(1-RTT)으로 끝납니다. 이전 버전인 1.2는 두 번입니다. 이 절차는 RFC 9846의 프로토콜 개요에 정의돼 있습니다. 그러면 실제로 얼마나 차이가 날까요? 숫자로 확인해 봤습니다.
2026-08-08 09:42 KST, 리눅스 워크스테이션 한 대에서 curl의 시간 측정값을
썼습니다. time_connect은 TCP 연결이 끝난 시각, time_appconnect은 TLS까지
끝난 시각이므로 두 값의 차이가 TLS 핸드셰이크에 쓴 시간입니다. 같은 주소로
10번씩 요청해 그중 최솟값을 골랐습니다(느린 쪽은 네트워크 흔들림이 섞이므로).
| 접속 대상 | TCP 연결(≈왕복 1회) | TLS 1.3 | TLS 1.2 | 1.2 − 1.3 |
|---|---|---|---|---|
example.com | 31ms | 95ms | 130ms | 35ms |
www.iana.org | 4ms | 90ms | 94ms | 4ms |
www.rfc-editor.org | 4ms | 91ms | 95ms | 4ms |
맨 오른쪽 칸과 맨 왼쪽 칸을 비교해 보세요. 버전 차이로 줄어든 시간이 TCP 연결 시간과 거의 같습니다. 왕복이 31ms인 곳에서는 35ms가 줄고, 4ms인 곳에서는 4ms가 줍니다. 교과서가 말하는 "왕복 한 번을 아낀다"가 그대로 측정된 것입니다.
그런데 이 표는 반대 이야기도 합니다
같은 표에서 세 줄 모두 90ms 안팎이 버전과 상관없이 공통으로 깔려 있습니다. 왕복이 4ms인 곳에서도 TLS에 90ms를 씁니다. 이 시간은 왕복 횟수가 아니라 암호 연산과 인증서 검증, 서버 처리 같은 다른 비용입니다.
그래서 "TLS 1.3으로 올리면 접속이 눈에 띄게 빨라진다"는 기대는 조건부로만 맞습니다. 아끼는 것은 딱 왕복 한 번이라서,
- 왕복이 짧은 국내 회선·같은 데이터센터 안이라면 차이는 몇 ms로 묻히고,
- 왕복이 긴 국제 회선이나 모바일 네트워크라면 그만큼 그대로 이득입니다.
이 값들은 장비 한 대·네트워크 한 곳·한 시점의 관측입니다. 성능 비교 지표가 아니라 "왕복 한 번만큼 줄어든다"는 사실을 확인하는 용도로만 읽어 주세요.
두 번째 접속은 한 번 더 빠릅니다
한 번 연결했던 서버에는 이전 접속에서 받아둔 재개용 정보를 써서, 첫 요청을 핸드셰이크와 함께 보내는 0-RTT가 가능합니다.
다만 0-RTT로 보낸 데이터는 공격자가 가로챘다가 나중에 그대로 다시 보낼 수 있습니다. 그래서 이 방식은 여러 번 실행돼도 결과가 같은 요청에만 쓰는 것이 원칙입니다. "조회는 괜찮지만 결제는 안 된다"고 이해하면 쉽습니다.
회선에 흐르지 않는 것
이 편에서 가장 이상하게 들리는 대목은 열쇠가 회선을 지나가지 않는다는 점입니다. 양쪽은 공개해도 되는 조각만 주고받고, 각자 자기 비밀과 합쳐 같은 값을 계산해 냅니다. 중간에서 오간 것을 전부 받아 적어도 그 값은 나오지 않습니다.
거기에 인증서와 CertificateVerify 서명이 "이 열쇠를 계산한 상대가 진짜 그 서버인지"를 확인해 줍니다. 두 가지가 끝나야 자물쇠가 잠기고, 그 뒤의 대화는 암호문으로 흐릅니다.
이 글에서 성격이 다른 세 가지
- 데모의 숫자 — a·b·A·B는 디피-헬만 원리의 비유적 단순화입니다. 실제 TLS 1.3은 여러 키 교환 방식을 지원하며, 공유 비밀과 HKDF로 용도별 열쇠를 만듭니다. 데모는 실제 암호 연산을 수행하지 않습니다.
- 위 표의 시간 — 2026-08-08 09:42 KST에 장비 한 대에서 잰 실제 관측값입니다. 다른 장비·다른 회선에서는 다르게 나옵니다.
- 본문의 설명 — 아래 RFC 문서에 정의된 동작을 풀어 쓴 것입니다.
데모가 다루지 않는 것: 인증서 사슬 검증의 세부, 실패한 핸드셰이크의 경고 메시지, 클라이언트 인증서, 세션 재개의 내부 구조. TLS는 대화 내용을 보호하지만 IP 주소, 통신 시각과 데이터 크기 같은 메타데이터까지 모두 숨기는 것은 아닙니다.
이 메시지가 포장되어 이동하는 모습은 네트워크 7계층 랩에서 볼 수 있습니다.