본문으로 건너뛰기
김신건의 로그

TLS / SSL

· 수정 · 📖 약 6분 · 2,521자/단어 #network #security #protocol #cryptography
TLS, SSL, Transport Layer Security, Secure Sockets Layer, tls, ssl

정의

TLS (Transport Layer Security) 는 TCP (또는 UDPQUIC) 위에서 동작하는 암호화·인증 프로토콜이다. SSL 은 TLS 의 전신 (Netscape 1995, 더 이상 사용되지 않음).

웹의 HTTPS 가 바로 “HTTP + TLS”. 인증서 검증, 키 교환, 암호화된 데이터 전송 모두 TLS 가 담당한다.

버전 역사

버전출시상태
SSL 1.01994내부 사용, 공개 안 됨
SSL 2.01995폐기 (취약점 다수)
SSL 3.01996폐기 (POODLE 공격)
TLS 1.01999폐기 (BEAST 공격)
TLS 1.12006폐기
TLS 1.22008현재도 널리 사용
TLS 1.32018권장, QUIC 에 통합됨

CAUTION

“SSL 인증서” 라는 용어는 관습적으로 남아있지만, 실제로 사용되는 건 TLS 다. SSL 1.0~3.0 은 모두 폐기되었다.

TLS 가 하는 일

  1. 서버 인증: 인증서로 “당신이 정말 example.com 입니까?” 검증
  2. 키 교환: 양측이 공유할 대칭키를 안전하게 생성 (ECDHE 등)
  3. 대칭 암호화: 이후 데이터를 AES-GCM, ChaCha20-Poly1305 등으로 암호화
  4. 무결성 검증: 메시지 변조 감지 (AEAD 알고리즘에 내장)

핵심 개념

비대칭 vs 대칭 암호의 역할 분리

알고리즘 예사용 시점특성
비대칭 (공개키)RSA, ECDSA, ECDHE핸드셰이크 단계느림, 인증서 검증·키 교환에만 사용
대칭AES-GCM, ChaCha20응용 데이터 단계빠름, 핸드셰이크에서 합의한 세션 키로 암호화

핸드셰이크에서 비대칭으로 안전하게 세션 키를 만들고, 이후 모든 데이터는 빠른 대칭 암호로 처리한다.

Forward Secrecy

ECDHE (Elliptic Curve Diffie-Hellman Ephemeral) 기반 키 교환은 매 세션마다 새 키를 만든다. 서버의 장기 비밀키가 나중에 유출되어도 과거 세션은 복호화 불가. TLS 1.3 은 이런 ephemeral 키 교환만 허용한다.

AEAD (Authenticated Encryption with Associated Data)

암호화와 무결성 검증을 한 번에 수행하는 알고리즘. 별도의 MAC 계산 없이 변조 감지 가능. TLS 1.3 은 AEAD 만 허용한다.

TLS 1.2 Full Handshake (2-RTT)

단계별 흐름:

  1. ClientHello: 클라이언트가 지원하는 cipher suite 목록 + random 값을 보낸다.
  2. ServerHello + Certificate + ServerKeyExchange + ServerHelloDone: 서버가 cipher 를 고르고, 인증서 체인 + 서버 측 키 교환 파라미터를 한 번에 보낸다.
  3. ClientKeyExchange + ChangeCipherSpec + Finished: 클라이언트가 pre-master 비밀을 보내고, 이후 대칭키 모드로 전환한다는 신호와 함께 Finished 메시지를 보낸다.
  4. ChangeCipherSpec + Finished: 서버도 대칭키 모드로 전환했음을 알리고 Finished 로 핸드셰이크 무결성을 검증한다.

2 RTT 소요. 응용 데이터 전송은 그 이후부터.

TLS 1.3 Handshake (1-RTT)

TLS 1.3 의 핵심 개선:

KeyShare 동봉

ClientHello 에 클라이언트가 미리 계산한 DH 공개키 후보 (KeyShare) 를 동봉한다. 서버는 같은 cipher / 그룹을 선택하면 즉시 같은 세션 키를 도출할 수 있다.

인증서를 핸드셰이크 안에서 암호화

TLS 1.2 에서는 인증서가 평문으로 전송되었으나 TLS 1.3 에서는 ServerHello 직후부터 핸드셰이크 메시지도 (handshake traffic key 로) 암호화된다. 사용자가 어떤 도메인을 방문하는지 외부에서 보기 어려워진다. (단, SNI 는 여전히 평문, ECH 로 보완 중)

0-RTT Resumption

이전 세션의 PSK (Pre-Shared Key) 또는 세션 티켓을 첨부하면, 첫 패킷에 응용 데이터를 동봉할 수 있다. RTT 0 으로 응답 시작 가능.

⚠️ 0-RTT 는 replay attack 위험이 있다. 같은 데이터가 재전송될 수 있으므로 멱등(idempotent) 요청 (GET 등) 에만 권장. 결제 같은 부작용 있는 요청은 1-RTT 로 강제해야 한다.

Cipher Suite 단순화

TLS 1.2 의 약한 cipher (RC4, 3DES, CBC mode 등) 가 모두 제거되었다. 5개의 AEAD cipher suite 만 남았다.

Cipher Suite

TLS 협상에서 선택하는 알고리즘 조합.

TLS 1.2 cipher suite 구조

TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
    │      │        │            │
    │      │        │            └── MAC/HMAC: SHA256
    │      │        └─────────────── 암호화: AES-128-GCM
    │      └──────────────────────── 서명/인증: RSA
    └─────────────────────────────── 키 교환: ECDHE

TLS 1.3 cipher suite (단순화)

키 교환은 별도로 협상하고 cipher suite 에서 분리됨:

Cipher SuiteAEAD 알고리즘HKDF
TLS_AES_256_GCM_SHA384AES-256-GCMSHA-384
TLS_AES_128_GCM_SHA256AES-128-GCMSHA-256
TLS_CHACHA20_POLY1305_SHA256ChaCha20-Poly1305SHA-256

ChaCha20-Poly1305: AES 하드웨어 가속이 없는 모바일 기기에서 더 빠르다. Android 저가형 기기에서 성능 이점이 크다.

인증서 체인 검증

브라우저는 서버가 보낸 인증서가 신뢰할 수 있는지 다음 절차로 검증한다.

  1. 도메인 일치 확인: 인증서의 SAN (Subject Alternative Name) 또는 CN 이 접속한 도메인과 일치하는가
  2. 만료 확인: notBefore ~ notAfter 범위 안에 있는가
  3. 체인 서명 검증: Leaf 인증서의 서명을 Intermediate CA 의 공개키로 검증, Intermediate 의 서명을 Root CA 의 공개키로 검증
  4. Root 일치 확인: 체인의 최상위가 OS / 브라우저의 truststore 에 내장된 신뢰된 Root CA 인가
  5. 폐기 여부 확인 (선택): OCSP (Online Certificate Status Protocol) 또는 CRL (Certificate Revocation List) 로 인증서가 revoke 되지 않았는지

서버는 보통 Leaf + Intermediate 만 전송한다. Root 는 클라이언트가 이미 truststore 에 가지고 있다.

인증서 발급 흐름

단계누가무엇을
1. CSR 생성서버 운영자도메인 + 공개키로 CSR (Certificate Signing Request) 만든다
2. 도메인 소유 증명운영자, CADNS TXT 레코드 (DNS-01) 또는 HTTP /.well-known/ (HTTP-01)
3. 서명CA검증 통과 시 CA 의 비밀키로 Leaf 인증서에 서명
4. 갱신서버 운영자Let’s Encrypt 는 90일, 보통 60일 전 자동 갱신

Let’s Encrypt, Cloudflare 등이 무료 + 자동화된 TLS 인증서를 제공하면서 HTTPS 가 사실상 표준이 되었다.

mTLS (Mutual TLS)

일반 TLS 는 서버만 인증서를 제시한다. mTLS 는 클라이언트도 인증서를 제시해 양방향 인증을 수행한다.

sequenceDiagram
    participant C as Client
    participant S as Server
    C->>S: ClientHello
    S->>C: ServerHello, Certificate, CertificateRequest
    C->>S: Certificate, CertificateVerify, Finished
    S->>C: Finished
    note over C,S: 양방향 인증 완료

주요 사용 사례:

  • 서비스 메시 (Istio, Linkerd): Pod 간 통신에 자동 mTLS 적용
  • 제로 트러스트 아키텍처: 내부 서비스 간 상호 인증
  • B2B API: 특정 파트너사만 접근 허용

SNI (Server Name Indication)

TLS ClientHello 에 접속하려는 도메인 이름을 포함하는 확장.

필요한 이유: 하나의 IP 에 여러 도메인(가상 호스팅) 이 있을 때, 서버가 어떤 인증서를 제시해야 할지 알기 위함.

ClientHello
  extensions:
    server_name: "www.example.com"   <- 평문 전송

CAUTION

SNI 는 평문으로 전송돼 네트워크 관찰자가 사용자가 방문하는 도메인을 볼 수 있다. ECH (Encrypted Client Hello) 가 이를 해결하는 중 (RFC 진행 중, Cloudflare 등 일부 지원).

ALPN (Application-Layer Protocol Negotiation)

ClientHello 에서 지원하는 응용 프로토콜을 협상하는 TLS 확장. 80/443 포트를 유지하면서 HTTP/1.1, HTTP/2 를 구분한다.

ClientHello
  extensions:
    alpn: ["h2", "http/1.1"]    <- 클라이언트 선호 순서

ServerHello
  extensions:
    alpn: "h2"                   <- 서버가 선택
# ALPN 협상 확인
openssl s_client -connect example.com:443 -alpn h2 2>&1 | grep "ALPN"

Session Resumption

TLS 핸드셰이크 비용을 줄이는 방법. 완전 핸드셰이크를 생략하고 이전 세션을 재사용.

방식TLS 버전서버 상태설명
Session ID1.2서버 저장서버가 ID 반환, 클라이언트가 다음 연결 때 제시
Session Ticket1.2 / 1.3클라이언트 저장서버가 암호화된 상태를 티켓으로 전달
PSK / 0-RTT1.3없음이전 세션 키로 첫 패킷에 데이터 포함

Session Ticket 은 서버 측 상태 저장이 불필요해 수평 확장에 유리하다. 단, 티켓 암호화 키가 로테이션되어야 Forward Secrecy 가 보장된다.

QUIC 와 TLS

QUIC 은 TLS 1.3 을 전송 계층에 통합했다.

프로토콜 조합핸드셰이크 RTT
TCP + TLS 1.2TCP (1 RTT) + TLS (2 RTT) = 3 RTT
TCP + TLS 1.3TCP (1 RTT) + TLS (1 RTT) = 2 RTT
QUIC (TLS 1.3 통합)1 RTT (full) 또는 0 RTT (resume)

QUIC 은 핸드셰이크와 전송을 분리하지 않고, 같은 패킷 안에서 처리한다. 결과적으로 HTTP/3 는 첫 페이지 로딩이 HTTP/2 보다 빠르다.

실전 예시

openssl 로 TLS 확인

# TLS 핸드셰이크 확인
openssl s_client -connect example.com:443 -servername example.com

# TLS 1.3 강제
openssl s_client -connect example.com:443 -tls1_3

# ALPN 협상 확인
openssl s_client -connect example.com:443 -alpn h2

# 인증서 상세 정보
openssl s_client -connect example.com:443 2>/dev/null | openssl x509 -noout -text

nginx TLS 1.3 설정

ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers HIGH:!aNULL:!MD5;

# Session resumption
ssl_session_tickets on;
ssl_session_timeout 1d;
ssl_session_cache shared:SSL:10m;

# OCSP Stapling
ssl_stapling on;
ssl_stapling_verify on;

# HSTS
add_header Strict-Transport-Security "max-age=31536000; includeSubDomains" always;

Let’s Encrypt 자동 갱신

# 인증서 발급
certbot --nginx -d example.com -d www.example.com

# 갱신 테스트
certbot renew --dry-run

# systemd timer 로 자동 갱신
systemctl enable --now certbot.timer

약점과 주의점

  • 인증서 관리 비용: 갱신 자동화 (ACME / certbot / cert-manager) 가 필수. 만료 사고는 흔하다.
  • 중간자 (MITM) 위험: 사내 프록시나 일부 디바이스가 truststore 에 자체 CA 를 심어 트래픽을 가로채는 경우가 있다.
  • 0-RTT replay: TLS 1.3 의 0-RTT 는 부작용 있는 요청에 사용 금지.
  • SNI 노출: 어떤 도메인에 접속하는지는 ClientHello 의 SNI 에 평문으로 노출됨. ECH 로 점진적 해결 중.
  • 신뢰 모델 자체의 한계: 약 150개 Root CA 중 하나라도 침해되면 임의의 도메인을 위장할 수 있음. Certificate Transparency (CT) 로 발급 로그 공개 의무화.

함정

WARNING

  1. TLS = 종단간 암호화? TLS 는 전송 경로 암호화. 서버에서 복호화되므로 서버 측 데이터는 평문. E2E 암호화는 별도 구현 필요.
  2. 인증서 = 보안 증명? 인증서는 도메인 소유를 증명할 뿐. 사이트의 콘텐츠나 운영 주체의 신뢰성을 보장하지 않음.
  3. 인증서 유출 = 치명적? 인증서에는 공개키만 포함됨. 비밀키가 유출돼야 실제 위험. 인증서 자체 유출은 무해.
  4. TLS 1.3 0-RTT 오남용: GET 이 아닌 POST/PUT/DELETE 에 0-RTT 를 허용하면 replay 공격으로 중복 처리 위험.
  5. HTTPS = 암호화 완료? 사내 프록시나 DLP 솔루션이 자체 CA 로 트래픽을 가로챌 수 있음 (SSL inspection).

관련 위키

  • QUIC - TLS 1.3 내장, 1-RTT 연결
  • TCP - TLS 가 동작하는 전송 계층
  • HTTP/2 - HTTPS 로 동작
  • HTTP/3 - QUIC 기반 (TLS 1.3 통합)
  • DNS - 인증서 발급 시 도메인 소유 증명
이 글의 용어 (6개)
[Network] DNS: 도메인 이름 해석network
정의 DNS (Domain Name System) 는 도메인 이름 ( ) 을 IP 주소 ( ) 로 변환하는 분산 데이터베이스. 인터넷의 가장 중요한 인프라. 기본 동작: 1. 클…
[Network] HTTP/2: multiplexing, HPACK, server push의 종말network
정의 HTTP/2 (2015, RFC 9113) 는 HTTP/1.1 의 문법은 유지하되 전송을 바이너리 + 멀티플렉싱 으로 바꾼다. Head-of-Line Blocking (HT…
[Network] HTTP/3: QUIC 위의 HTTP, 0-RTT, connection migrationnetwork
정의 HTTP/3 (2022, RFC 9114)는 HTTP의 전송 레이어를 TCP 에서 QUIC 으로 교체한 버전이다. UDP 위에 QUIC, QUIC 위에 HTTP 구조다. 핵…
QUICnetwork
정의 QUIC (Quick UDP Internet Connections)은 Google이 2012년 처음 제안하고 2021년 RFC 9000으로 표준화된 UDP 기반 전송 프로토…
TCPnetwork
정의 TCP (Transmission Control Protocol) 는 신뢰성 있는 연결 지향 전송 계층 프로토콜이다. RFC 9293 으로 정의되어 있다. HTTP/1.1·2…
UDPnetwork
정의 UDP (User Datagram Protocol)는 비연결·비신뢰 전송 계층 프로토콜이다. RFC 768 (1980) 로 정의되었다. TCP 와 대비된다. "보내고 잊는다…

💬 댓글

사이트 검색 / 명령어

검색

스크롤 = 확대/축소 · 드래그 = 이동 · 0 = 원래 크기 · ESC = 닫기