62. HTTPS와 TLS Handshake — 암호화된 통신에서 볼 수 있는 것

changseop lee·5일 전

📚 네트워크 · 패킷 분석 › 02. 포트 · 프로토콜 분석 — 62편
이전 글: 61. HTTP 요청·응답 구조 · 다음 글: 63. FTP Active·Passive 모드와 보안
참고(01. TCP/IP 구조 이해): 41. TCP 3-Way Handshake — 연결이 성립했다는 증거 — TLS Handshake는 TCP 연결 성립 뒤에 시작됨

1. 왜 알아야 하는가

오늘날 웹 트래픽의 대부분은 HTTPS입니다. 앞의 두 글에서 본 메서드·경로·상태코드는 HTTPS에서는 네트워크 구간에서 보이지 않습니다. 그렇다고 관제가 아무것도 볼 수 없는 것은 아닙니다.

  • 누가(IP) 어디로(IP·포트) 얼마나(바이트·시간) 통신했는가
  • 어떤 도메인에 접속하려 했는가(SNI, 환경에 따라 다름)
  • 서버가 어떤 인증서를 제시했는가(TLS 버전에 따라 다름)
  • 어떤 TLS 버전·암호 스위트가 협상되었는가

이 경계를 정확히 알아야 "HTTPS라서 확인 불가"라고 성급하게 결론 내리거나, 반대로 "SNI가 있으니 목적지는 확실하다"고 과신하는 실수를 피할 수 있습니다. 이번 글은 TLS Handshake를 개념 수준에서 정리하고, 필드 단위 패킷 해석은 03. Wireshark 패킷 분석 시리즈로 넘깁니다.


2. 핵심 개념

2-1. HTTPS = HTTP + TLS

HTTPS는 HTTP 메시지를 TLS(Transport Layer Security) 로 암호화해 전송하는 방식이며 기본 포트는 443/TCP입니다. TLS가 제공하는 것은 세 가지입니다.

기능의미담당 요소
기밀성제3자가 내용을 읽지 못함대칭키 암호화 (세션 키)
무결성전송 중 변조 탐지메시지 인증 (AEAD 등)
서버 인증접속한 서버가 그 도메인의 주인인지 확인인증서와 인증기관(CA) 서명

2-2. Handshake에 등장하는 주요 요소

요소설명
ClientHello클라이언트가 지원하는 TLS 버전, 암호 스위트 목록, 난수, 확장(Extension)을 제시
SNI (Server Name Indication)ClientHello의 확장. 접속하려는 도메인 이름을 서버에 알림 (한 IP에 여러 사이트가 있어서 필요)
ServerHello서버가 버전·암호 스위트를 선택해 응답
Certificate서버 인증서 (주체 도메인, 발급자, 유효기간, 공개키)
키 교환양쪽이 세션 키를 만들기 위한 값 교환 (현재는 주로 ECDHE)
FinishedHandshake 내용이 변조되지 않았음을 서로 확인

2-3. TLS 1.2와 TLS 1.3 비교 (개념)

항목TLS 1.2TLS 1.3
완전한 Handshake 왕복2-RTT1-RTT
서버 인증서 전송평문 (네트워크에서 보임)암호화 (네트워크에서 보이지 않음)
키 교환RSA 키 전송 방식 또는 (EC)DHE(EC)DHE만 사용 → 전방 비밀성 기본
암호 스위트선택지 많음, 구형 조합 존재소수의 AEAD 스위트로 정리
버전 표시Handshake의 버전 필드호환성 때문에 기존 버전 필드는 1.2로 두고, supported_versions 확장으로 1.3 협상
SNI평문평문 (ECH 적용 시 예외, 아래 참고)

2-4. 무엇이 보이고 무엇이 암호화되는가

정보네트워크에서 보이는가비고
출발지·목적지 IP, 포트보임IP·TCP 헤더
통신량·시간·연결 빈도보임흐름 통계
TLS 버전, 암호 스위트보임Hello 메시지
SNI (도메인)대부분 보임ECH 적용 시 실제 도메인이 숨겨질 수 있음
서버 인증서TLS 1.2 보임 / TLS 1.3 안 보임
URL 경로·쿼리, 메서드안 보임HTTP 메시지 전체가 암호화
요청·응답 헤더, 쿠키, 본문안 보임
상태코드안 보임웹 서버 로그에서 확인

ECH(Encrypted Client Hello) 는 SNI를 포함한 ClientHello의 민감한 부분을 암호화하는 확장입니다. 적용되면 네트워크에 보이는 바깥쪽 ClientHello의 SNI에는 실제 목적지가 아니라 서비스 제공자(예: CDN)의 공용 이름이 보일 수 있습니다. 일부 브라우저와 CDN에서 적용이 진행 중인 단계로, 환경과 시점에 따라 적용 여부가 다릅니다. 따라서 "SNI는 항상 실제 도메인을 보여준다"고 단정하지 않습니다.


3. 동작 원리

TCP 3-Way Handshake가 끝난 뒤 TLS Handshake가 이어집니다.

TLS 1.3 핸드셰이크
그림 1. 관제에서 볼 수 있는 메타데이터(SNI·버전)와 볼 수 없는 내용(URL·본문)의 경계

TLS 1.2 (ECDHE 기준, 개념도)
[클라이언트]                                              [서버 :443]
  ClientHello (버전·스위트 목록·SNI) ─────────────────────→
  ←─── ServerHello, Certificate(평문), ServerKeyExchange, ServerHelloDone
  ClientKeyExchange, ChangeCipherSpec, Finished ─────────→
  ←──────────────────────────── ChangeCipherSpec, Finished
                         ↓ (2-RTT 후)
  ════════════ 암호화된 HTTP 요청·응답 ════════════

TLS 1.3 (개념도)
[클라이언트]                                              [서버 :443]
  ClientHello (key_share·supported_versions·SNI) ──────→
  ←─── ServerHello (key_share)
       [이후 암호화] EncryptedExtensions, Certificate, CertificateVerify, Finished
  [암호화] Finished ───────────────────────────────────→
                         ↓ (1-RTT 후)
  ════════════ 암호화된 HTTP 요청·응답 ════════════

TLS 1.3에서는 ServerHello 직후부터 암호화되므로 인증서가 네트워크에 평문으로 나타나지 않습니다. 네트워크 장비가 인증서 정보를 기록하던 방식이 TLS 1.3 환경에서는 제한되는 이유입니다. 또한 TLS 1.3 패킷에도 중간 장비 호환성을 위해 ChangeCipherSpec 메시지가 보일 수 있으나, 1.2에서와 같은 의미는 아닙니다.


4. 실제 명령어 / 실습

실습 환경: 본인 소유 Linux VM (Rocky Linux 또는 Ubuntu). 인터페이스 이름은 ens33을 예시로 사용합니다. 실습용 TLS 서버는 VM 내부에서만 실행합니다.

도구 설치:

# Rocky Linux
sudo dnf install -y openssl tcpdump wireshark-cli
# Ubuntu
sudo apt install -y openssl tcpdump tshark

4-1. 실습용 자체 서명 인증서와 TLS 서버

mkdir -p ~/tlslab && cd ~/tlslab
openssl req -x509 -newkey rsa:2048 -nodes -keyout key.pem -out cert.pem -days 30 -subj "/CN=lab.local"
openssl s_server -accept 8443 -cert cert.pem -key key.pem -www

4-2. 클라이언트에서 Handshake 결과 확인 (다른 터미널)

openssl s_client -connect 127.0.0.1:8443 -servername lab.local -brief </dev/null
openssl s_client -connect 127.0.0.1:8443 -servername lab.local -tls1_2 -brief </dev/null

4-3. 인증서 정보 추출

openssl s_client -connect 127.0.0.1:8443 -servername lab.local </dev/null 2>/dev/null \
  | openssl x509 -noout -subject -issuer -dates

공개 웹사이트의 인증서도 같은 방법으로 확인할 수 있습니다(예: -connect example.com:443 -servername example.com).

📷 [실습 화면 삽입] -brief 출력에서 TLS 1.3과 1.2의 프로토콜·암호 스위트가 다르게 보이는 화면

4-4. 네트워크에서 보이는 SNI 확인

VM에서 외부 HTTPS 사이트에 접속하며 캡처한 뒤, ClientHello의 SNI만 추출합니다.

sudo tcpdump -ni ens33 -c 30 -w /tmp/tls.pcap 'tcp port 443' &
curl -s -o /dev/null https://example.com
sleep 2; sudo pkill tcpdump
# (tcpdump가 권한을 낮춰 파일을 쓰는 배포판이 있어 홈 디렉터리 대신 /tmp에 저장)
tshark -r /tmp/tls.pcap -Y 'tls.handshake.type == 1' \
  -T fields -e ip.src -e ip.dst -e tls.handshake.extensions_server_name

ClientHello 필드 하나하나의 해석은 03. Wireshark 패킷 분석 시리즈에서 다룹니다.


5. 결과 확인

형식 예시(값은 환경마다 다름):

$ openssl s_client -connect 127.0.0.1:8443 -servername lab.local -brief </dev/null
Protocol version: TLSv1.3
Ciphersuite: TLS_AES_256_GCM_SHA384
Peer certificate: CN = lab.local
Verification error: self-signed certificate

$ ... | openssl x509 -noout -subject -issuer -dates
subject=CN = lab.local
issuer=CN = lab.local
notBefore=Sep 26 05:10:00 2026 GMT
notAfter=Oct 26 05:10:00 2026 GMT

$ tshark ... -e tls.handshake.extensions_server_name
192.168.10.20	203.0.113.10	example.com
확인 항목읽는 법
Protocol / Ciphersuite협상된 TLS 버전과 암호 스위트
subject = issuer자체 서명 인증서 (공인 CA 발급이 아님)
Verification error클라이언트가 신뢰할 수 없는 인증서 → 운영 서비스라면 확인 대상
SNI 값네트워크 캡처에서 확인되는 접속 도메인
  • TLS 1.3과 1.2의 협상 결과를 각각 확인했다
  • 인증서의 주체·발급자·유효기간을 추출했다
  • 캡처에서 SNI가 평문으로 보이는 것을 확인했다
  • 캡처에서 URL 경로·헤더는 보이지 않는 것을 확인했다

📷 [실습 화면 삽입] tshark로 ClientHello의 SNI가 추출된 화면


6. 패킷 / 로그 분석

Zeek의 ssl.log, Suricata의 tls 이벤트처럼 TLS 메타데이터를 기록하는 도구는 대체로 버전·암호 스위트·SNI·인증서 정보를 남깁니다. 필드 구성 형식 예시(도구·버전에 따라 필드명이 다름):

ts=2026-09-26T14:20:31  src=192.168.10.30:51044  dst=203.0.113.10:443
version=TLSv1.3  cipher=TLS_AES_128_GCM_SHA256  server_name=www.example.com
관찰정상일 수 있는 경우의심해야 하는 경우
자체 서명·만료 인증서내부 관리 장비, 개발 서버외부 목적지인데 자체 서명, 인증서 CN과 SNI 불일치
SNI 없이 IP로 직접 TLS 연결일부 애플리케이션·장비 통신사용자 PC가 평판 정보 없는 외부 IP와 SNI 없이 반복 통신
SSLv3·TLS 1.0/1.1 사용교체되지 않은 구형 장비외부 공개 서버가 구형 버전 허용 (취약 설정 점검 대상)
일정 간격의 짧은 TLS 연결 반복업데이트 확인, 동기화 서비스정해진 주기로 같은 목적지에 소량 통신 반복 (비코닝 가능성)
드문 도메인·신규 도메인 SNI새로 쓰기 시작한 SaaS조직 내 한두 단말만 접속하는 무작위 형태 도메인
443 포트인데 TLS Handshake가 없음—443을 다른 프로토콜 통로로 사용 (21편에서 다룸)

TLS ClientHello의 구성(버전·스위트·확장 순서)을 해시로 만든 JA3·JA4 같은 클라이언트 지문도 탐지에 활용됩니다. 다만 브라우저가 확장 순서를 무작위화하는 등의 변화로 지문 방식마다 한계가 있어, 단독 근거보다는 보조 지표로 씁니다.


7. 보안관제 관점

위치확인 가능한 것한계
방화벽·NetFlowIP·포트·통신량·시간도메인·내용 불가
IDS / 네트워크 메타데이터(Zeek 등)SNI, 버전, 스위트, (1.2) 인증서내용 불가, 1.3 인증서 불가
TLS 복호화 프록시URL·헤더·본문개인정보·법적 검토 필요, 인증서 고정 앱 예외 (04. 네트워크 장비 실습 시리즈에서 다룸)
웹 서버 로그복호화 후의 요청줄·상태코드자기 서버로 들어오는 요청만
DNS 로그TLS 이전의 도메인 질의DoH 등 암호화 DNS 사용 시 누락 가능 (08편에서 다룸)

한계와 오탐 주의

  • HTTPS 구간에서는 메서드·경로·상태코드를 네트워크에서 볼 수 없습니다. 웹 공격 판단은 웹 서버·WAF 로그가 1차 근거입니다.
  • SNI는 클라이언트가 넣는 값이며, ECH 적용 시 실제 도메인과 다를 수 있습니다. DNS 질의 로그와 교차 확인합니다.
  • 자체 서명 인증서는 내부망에서 흔합니다. 목적지가 내부인지 외부인지부터 구분합니다.
  • 암호화 트래픽의 탐지 룰 설계는 06. 방화벽 · IDS/IPS 분석 시리즈, 위장 통신은 21. 정상 포트로 위장한 통신에서 다룹니다.

8. 핵심 정리

  • HTTPS는 HTTP를 TLS로 암호화한 것이며, TLS는 기밀성·무결성·서버 인증을 제공합니다.
  • TLS 1.2는 2-RTT에 인증서가 평문, TLS 1.3은 1-RTT에 ServerHello 이후 인증서까지 암호화됩니다.
  • 네트워크에서 보이는 것은 IP·포트·통신량·TLS 버전·암호 스위트·SNI이며, URL·헤더·본문·상태코드는 보이지 않습니다.
  • SNI는 대부분 평문이지만 ECH가 적용되면 실제 도메인이 숨겨질 수 있으므로 DNS 로그와 함께 봅니다.
  • 인증서 이상(자체 서명·불일치·만료), SNI 없는 연결, 주기적 반복 연결이 암호화 트래픽의 주요 관찰 포인트입니다.

다음 글: 07. DNS 레코드와 질의 유형

profile
코드에 숨겨진 위협을 읽고 AI로 보안의 미래를 설계합니다. 프론트엔드 개발 경험을 자산 삼아 더 견고하고 지능적인 보안 운영 시스템을 구축해 나가는 과정을 기록합니다

0개의 댓글