← 아티클 목록

TLS 핸드셰이크 과정 이해 — openssl로 단계별 확인하기

2027-06-07#networking#tls#보안

HTTPS 연결이 느리거나 SSL certificate problem이 뜰 때, 무슨 일이 벌어지는지 모르면 어디를 고칠지도 모릅니다. TLS 핸드셰이크는 평문 통신을 암호화 채널로 바꾸는 협상 절차입니다. 단계를 알면 어느 단계에서 막혔는지 메시지로 읽어낼 수 있습니다.

핸드셰이크가 하는 일

TCP 연결(3-way handshake)이 끝난 뒤, 본격적인 데이터를 주고받기 전에 클라이언트와 서버는 세 가지를 합의합니다: 어떤 암호 방식을 쓸지, 서버가 진짜인지(인증서), 이 세션에서 쓸 대칭키. 이게 끝나야 비로소 암호화된 HTTP 요청이 흐릅니다.

단계별 흐름

  1. ClientHello — 클라이언트가 지원하는 TLS 버전·암호 스위트(cipher suite) 목록과 랜덤값을 보냅니다.
  2. ServerHello — 서버가 그중 하나를 고르고, 자신의 랜덤값을 보냅니다.
  3. Certificate — 서버가 인증서 체인을 보냅니다. 클라이언트는 신뢰할 수 있는 CA가 서명했는지, 만료되지 않았는지, 이름이 맞는지 검증합니다.
  4. 키 교환 — 양쪽 랜덤값과 (ECDHE 등) 키 교환으로 동일한 세션 키를 만들어냅니다. 이후 통신은 이 대칭키로 암호화됩니다.
  5. Finished — 양쪽이 협상이 변조되지 않았음을 확인하고 암호화 채널이 열립니다.

TLS 1.3에서는 왕복(RTT)이 줄어 이 과정이 한 번의 왕복으로 끝나, 1.2보다 연결이 빠릅니다.

openssl로 직접 보기

로컬 터미널
openssl s_client -connect example.com:443 -servername example.com

-servername은 SNI(같은 IP에 여러 도메인이 있을 때 어느 인증서를 줄지 알려주는 확장)를 지정합니다. 이걸 빼면 엉뚱한 기본 인증서가 와서 이름 불일치가 날 수 있습니다.

출력에서 핵심은 이 줄들입니다.

OUTPUT
Protocol  : TLSv1.3           ← 협상된 버전
Cipher    : TLS_AES_256_GCM_SHA384   ← 선택된 암호 스위트
Verify return code: 0 (ok)    ← 인증서 검증 결과

Verify return code가 0이 아니면 인증서 문제입니다. 만료(certificate has expired), 체인 누락(unable to get local issuer certificate), 이름 불일치가 대표적입니다.

증상별 점검

증상의미점검
연결이 느림핸드셰이크 왕복 과다TLS 1.3·세션 재사용 확인
certificate has expired인증서 만료갱신·자동 갱신(certbot)
unable to get local issuer중간 인증서 누락서버에 풀체인 설치
이름 불일치SNI·인증서 도메인 불일치-servername·SAN 확인

점검 순서

로컬 터미널
openssl s_client -connect <host>:443 -servername <host>
# Protocol·Cipher로 협상 결과 확인
# Verify return code로 인증서 검증 확인

TLS 핸드셰이크와 인증서 검증을 직접 끊어보고 진단하는 실습은 네트워크 트랙에서 회원가입 없이 무료로 익힐 수 있습니다.