TLS 1.2 vs 1.3 핸드셰이크 완벽 비교: 성능과 보안의 혁명적 변화

"웹사이트 로딩이 왜 이렇게 빨라졌을까요?" 최근 몇 년 사이 인터넷 사용자들이 체감하는 이 변화의 핵심에는 TLS 1.3이 있습니다. TLS 1.3은 기존 TLS 1.2 대비 더 빠른 핸드셰이크와 향상된 보안성을 제공하며, Zero Round-Trip Time(0-RTT) 기능을 통해 성능을 크게 개선했습니다.

실제로 TLS 핸드셰이크 시간은 50% 이상 단축되었고, 동시에 보안 취약점들도 대폭 개선되었습니다. 이 가이드에서는 두 버전의 핸드셰이크 과정을 상세히 비교하며, 왜 TLS 1.3으로의 업그레이드가 필수인지 알아보겠습니다.

 

TLS 핸드셰이크란? 기본 개념 이해

암호화 통신의 시작점

암호화 통신의 시작점
암호화 통신의 시작점

TLS(Transport Layer Security) 핸드셰이크는 클라이언트와 서버가 안전한 암호화 통신을 시작하기 위해 거쳐야 하는 초기 협상 과정입니다. 이 과정에서 안전한 연결과 세션 키를 생성합니다.

핸드셰이크 과정에서는 다음과 같은 중요한 작업들이 수행됩니다:

  • 암호화 알고리즘 협상: 클라이언트와 서버가 지원하는 암호화 방식 중 최적의 것을 선택
  • 인증서 검증: 서버의 신원을 확인하고 공개키를 획득
  • 세션 키 생성: 실제 데이터 암호화에 사용할 대칭키 생성
  • 보안 매개변수 설정: 연결 보안을 위한 각종 설정값 협의

Round-Trip Time의 중요성

네트워크 통신에서 RTT(Round-Trip Time)는 클라이언트가 서버에 요청을 보내고 응답을 받기까지의 시간입니다. 핸드셰이크에서 RTT가 중요한 이유는 각 RTT마다 네트워크 지연시간이 누적되기 때문입니다.

예를 들어, 한국에서 미국 서버에 접속할 때 RTT가 150ms라면:

  • TLS 1.2: 2-RTT = 300ms의 추가 지연
  • TLS 1.3: 1-RTT = 150ms의 추가 지연

이 차이는 사용자 경험에 직접적인 영향을 미칩니다.

 

TLS 1.2 핸드셰이크 상세 분석

TLS 1.2 핸드셰이크
TLS 1.2 핸드셰이크

2-RTT 핸드셰이크 과정

TLS 1.2 핸드셰이크는 두 번의 왕복(2-RTT) 또는 메시지 교환을 통해 완료됩니다. 전체 과정을 단계별로 살펴보겠습니다.

1단계: Client Hello (RTT 1/2 - 첫 번째 요청)

클라이언트가 서버에 연결을 시작하며 다음 정보를 전송합니다:

Client Hello 메시지 구성:
- TLS 버전: 1.2
- 지원 가능한 암호화 스위트 목록
- 클라이언트 난수 (Client Random)
- 세션 ID (세션 재사용용)
- SNI (Server Name Indication)

암호화 스위트 예시:

  • TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
  • TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
  • TLS_DHE_RSA_WITH_AES_256_CBC_SHA256

2단계: Server Response (RTT 1/2 - 첫 번째 응답)

서버는 클라이언트의 요청을 받고 다음과 같이 응답합니다:

Server Hello + 추가 메시지들:
- Server Hello: 선택된 암호화 스위트, 서버 난수
- Certificate: 서버 인증서 (공개키 포함)
- Server Key Exchange: 키 교환 매개변수
- Server Hello Done: 서버 메시지 완료 알림

3단계: Client Key Exchange (RTT 2/2 - 두 번째 요청)

클라이언트는 서버 인증서를 검증한 후 키 교환을 진행합니다:

Client Key Exchange + 추가 메시지들:
- Client Key Exchange: Pre-master Secret 전송
- Change Cipher Spec: 암호화 시작 알림
- Finished: 핸드셰이크 검증 데이터

4단계: Server Confirmation (RTT 2/2 - 두 번째 응답)

서버가 최종 확인 메시지를 보내며 핸드셰이크가 완료됩니다:

Server Final Messages:
- Change Cipher Spec: 서버도 암호화 시작
- Finished: 서버 핸드셰이크 완료 확인

 

TLS 1.2의 보안 취약점들

알려진 보안 이슈:

  • POODLE 공격: CBC 패딩 오라클 공격에 취약
  • BEAST 공격: CBC 모드의 초기화 벡터 문제
  • CRIME/BREACH: 압축을 이용한 정보 누출
  • Heartbleed: OpenSSL 구현상의 메모리 누출
  • 약한 암호화 스위트: RC4, DES 등 취약한 알고리즘 지원

TLS 1.3 핸드셰이크의 혁신적 변화

TLS 1.3 핸드셰이크
TLS 1.3 핸드셰이크

1-RTT 핸드셰이크로의 진화

tls 1.2와 1.3의 차이점

TLS v1.3에서는 TLS v1.2의 2-Round에서 1-Round로 줄어들어 핸드셰이크 과정이 크게 간소화되었습니다. 이는 패킷 수를 6개에서 3개로 절반으로 감소시켰습니다.

1단계: Client Hello (RTT 1/1 - 유일한 요청)

TLS 1.3의 Client Hello는 더욱 효율적으로 설계되었습니다:

TLS 1.3 Client Hello:
- TLS 버전: 1.3
- 지원 암호화 스위트 (간소화된 목록)
- 클라이언트 난수
- Key Share: 키 교환을 위한 공개키 포함 (중요!)
- Signature Algorithms: 지원하는 서명 알고리즘
- Supported Groups: 지원하는 타원곡선/DH 그룹

핵심 차이점: Client Hello 단계에서 이미 Key Share 정보를 포함하여 키 교환을 미리 시작합니다.

2단계: Server Response (RTT 1/1 - 유일한 응답)

서버는 한 번의 응답으로 핸드셰이크를 거의 완료합니다:

TLS 1.3 Server Response:
- Server Hello: 선택된 암호화 스위트 + Key Share
- {Encrypted Extensions}: 확장 정보 (이미 암호화됨)
- {Certificate}: 서버 인증서 (암호화됨)
- {Certificate Verify}: 인증서 서명 검증 (암호화됨)
- {Finished}: 핸드셰이크 완료 (암호화됨)

중요한 개선사항: 인증서와 관련 정보들이 이미 암호화되어 전송됩니다.

3단계: Client Confirmation (데이터와 함께 전송 가능)

클라이언트의 최종 확인은 매우 간단합니다:

Client Final:
- {Finished}: 핸드셰이크 완료 확인
- Application Data: 실제 애플리케이션 데이터 (즉시 전송 가능)

보안성 대폭 개선

TLS 1.3는 TLS 1.2보다 더 나은 보안성을 제공하며, 해커들이 크랙하는 방법을 찾아낸 알고리즘 등 핸드셰이크 과정의 알려진 취약점들을 해결합니다.

개선된 보안 요소:

  • Perfect Forward Secrecy 강제: 모든 키 교환에서 PFS 보장
  • 취약한 암호화 알고리즘 제거: RC4, DES, 3DES, MD5, SHA1 완전 제거
  • 압축 기능 제거: CRIME/BREACH 공격 차단
  • 서명 알고리즘 개선: RSA-PSS, EdDSA 등 최신 알고리즘 사용
  • 핸드셰이크 암호화: 인증서 정보도 암호화하여 프라이버시 보호

 

0-RTT: TLS 1.3의 궁극적 성능 최적화

Zero Round-Trip Time의 개념

TLS 1.3는 0-RTT 핸드셰이크를 제공하여 클라이언트와 서버가 이전에 설정된 TLS 세션을 재개할 수 있습니다. 이는 더 빠르고 안전한 핸드셰이크를 가능하게 합니다.

0-RTT는 이전 연결에서 생성된 세션 키를 재사용하여 첫 번째 메시지부터 애플리케이션 데이터를 전송할 수 있게 합니다.

0-RTT 동작 원리

초기 연결 (1-RTT Full Handshake)

Client → Server: Client Hello + Key Share
Server → Client: Server Hello + Key Share + {Certificate} + {Finished}
Client → Server: {Finished}

세션 종료 시 서버는 **PSK (Pre-Shared Key)**와 함께 Session Ticket을 클라이언트에게 전달합니다.

재연결 (0-RTT Resumption)

Client → Server: Client Hello + PSK + Early Data (애플리케이션 데이터!)
Server → Client: Server Hello + {Finished} + Application Data

클라이언트는 첫 번째 메시지부터 실제 애플리케이션 데이터를 함께 전송할 수 있습니다!

0-RTT의 보안 고려사항

Replay Attack 취약점

0-RTT 핸드셰이크 모드는 클라이언트가 첫 번째 메시지(ClientHello)에서 연결을 설정하고 애플리케이션 데이터를 보낼 수 있게 하지만, 이로 인해 재전송 공격의 가능성이 열립니다.

위험 시나리오:

  • 공격자가 0-RTT 데이터를 캡처하여 나중에 재전송
  • 멱등성이 없는 작업(예: 결제, 데이터 수정)에서 위험
  • 서버가 동일한 요청을 중복 처리할 가능성

완화 방법:

  • 단일 사용 티켓: 한 번 사용된 세션 티켓은 무효화
  • 시간 제한: 0-RTT 데이터에 짧은 유효시간 설정
  • 멱등성 보장: 0-RTT로는 안전한 GET 요청만 허용
  • Anti-replay 매커니즘: 서버에서 중복 요청 탐지 및 차단

성능 비교: 실제 측정값으로 보는 개선효과

핸드셰이크 시간 비교

실제 네트워크 환경에서의 측정 결과:

조건 TLS 1.2 TLS 1.3 TLS 1.3 (0-RTT)

로컬 네트워크 (1ms RTT) 2ms 1ms 0ms
국내 서버 (20ms RTT) 40ms 20ms 0ms
해외 서버 (150ms RTT) 300ms 150ms 0ms
위성 인터넷 (600ms RTT) 1200ms 600ms 0ms

CPU 사용량 및 처리량 개선

암호화 처리 성능:

  • 더 효율적인 알고리즘: ChaCha20-Poly1305, AES-GCM 최적화
  • 하드웨어 가속: AES-NI, AVX2 명령어 세트 활용
  • 메모리 사용량 감소: 간소화된 상태 머신으로 약 15% 감소

실제 웹서버 성능 개선:

  • 동시 연결 처리량: 약 25% 증가
  • 배터리 소모: 모바일 기기에서 약 30% 감소
  • 대역폭 사용량: 핸드셰이크 오버헤드 50% 감소

암호화 스위트의 진화

TLS 1.2 암호화 스위트의 복잡성

TLS 1.2에서는 수많은 암호화 스위트 조합이 가능했습니다:

TLS 1.2 암호화 스위트 구조:
TLS_[키교환]_[서명]_WITH_[대칭암호]_[해시함수]

예시:
- TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384
- TLS_DHE_RSA_WITH_AES_128_CBC_SHA256
- TLS_RSA_WITH_AES_256_CBC_SHA (취약함)

이런 복잡성으로 인해 잘못된 설정이나 취약한 조합을 선택할 위험이 있었습니다.

TLS 1.3의 간소화된 접근방식

TLS 1.3에서는 검증된 안전한 조합만 미리 정의했습니다:

TLS 1.3 암호화 스위트 (전체 5개):
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_GCM_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256

키 교환과 서명은 별도 협상:

  • 키 교환: ECDHE (secp256r1, secp384r1, secp521r1, x25519, x448)
  • 서명: RSA-PSS, ECDSA, EdDSA

이런 분리로 조합의 복잡성을 줄이고 보안성을 향상시켰습니다.

실무 구현 가이드

서버 설정 최적화

Apache 설정 (httpd.conf):

# TLS 1.3 활성화
SSLProtocol all -SSLv2 -SSLv3 -TLSv1 -TLSv1.1 +TLSv1.2 +TLSv1.3

# TLS 1.3 암호화 스위트
SSLCipherSuite TLS_AES_256_GCM_SHA384:TLS_CHACHA20_POLY1305_SHA256:TLS_AES_128_GCM_SHA256

# 0-RTT 설정 (주의깊게 사용)
SSLSessionTickets on
SSLSessionCache shmcb:/var/cache/mod_ssl/scache(512000)

Nginx 설정 (nginx.conf):

# TLS 1.3 설정
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE+AESGCM:ECDHE+CHACHA20:DHE+AESGCM:DHE+CHACHA20:!aNULL:!MD5:!DSS;
ssl_prefer_server_ciphers off;

# TLS 1.3 Early Data (0-RTT) 활성화
ssl_early_data on;
proxy_set_header Early-Data $ssl_early_data;

클라이언트 측 최적화

브라우저 설정 확인:

  • Chrome: chrome://flags/#tls13-variant 에서 TLS 1.3 활성화
  • Firefox: about:config에서 security.tls.version.max = 4 설정
  • Safari: 기본적으로 TLS 1.3 지원 (macOS 10.14+)

프로그래밍 언어별 구현:

Python (requests 라이브러리):

import ssl
import requests

# TLS 1.3 강제 사용
ssl_context = ssl.create_default_context()
ssl_context.minimum_version = ssl.TLSVersion.TLSv1_3
ssl_context.maximum_version = ssl.TLSVersion.TLSv1_3

session = requests.Session()
adapter = requests.adapters.HTTPAdapter()
session.mount('https://', adapter)

response = session.get('<https://example.com>')
print(f"TLS Version: {response.raw.version}")

Node.js 설정:

const https = require('https');
const tls = require('tls');

const options = {
  hostname: 'example.com',
  port: 443,
  path: '/',
  method: 'GET',
  // TLS 1.3 설정
  minVersion: 'TLSv1.3',
  maxVersion: 'TLSv1.3'
};

const req = https.request(options, (res) => {
  console.log(`TLS Version: ${res.socket.getProtocol()}`);
});

마이그레이션 전략 및 호환성 고려사항

점진적 마이그레이션 계획

1단계: 현재 환경 분석

# 현재 TLS 버전 확인
openssl s_client -connect yourdomain.com:443 -tls1_3

# 클라이언트 지원 현황 확인 (서버 로그 분석)
grep "TLS" /var/log/nginx/access.log | awk '{print $x}' | sort | uniq -c

2단계: 테스트 환경 구축

  • 스테이징 서버에 TLS 1.3 적용
  • 다양한 클라이언트 환경에서 테스트
  • 성능 벤치마크 수행

3단계: 프로덕션 적용

  • TLS 1.2와 1.3 동시 지원으로 시작
  • 클라이언트 지원 현황 모니터링
  • 점진적으로 TLS 1.3 우선순위 증가

호환성 이슈 해결

오래된 클라이언트 지원:

  • Windows 7: 기본적으로 TLS 1.3 미지원 (업데이트 필요)
  • Android 8.0 이하: TLS 1.3 부분 지원
  • iOS 12.0 이하: TLS 1.3 미지원

해결 방안:

# 클라이언트별 TLS 버전 분기 처리
map $ssl_preread_server_name $backend_pool {
    ~^old-clients\\. old_tls12_backend;
    default new_tls13_backend;
}

보안 모니터링 및 문제 해결

TLS 1.3 특화 모니터링 포인트

핸드셰이크 실패 분석:

# OpenSSL을 이용한 TLS 1.3 연결 디버그
openssl s_client -connect example.com:443 -tls1_3 -debug -msg

# Wireshark 필터 (TLS 1.3 핸드셰이크만 표시)
tls.handshake.version == 0x0304

성능 메트릭 모니터링:

  • 핸드셰이크 완료시간: 1-RTT vs 2-RTT 비교
  • 0-RTT 사용률: Early Data 사용 빈도
  • 암호화 스위트 분포: 클라이언트별 선택 패턴
  • 에러율: TLS 1.3 관련 연결 실패

일반적인 문제 해결

문제: TLS 1.3 연결 실패

원인 분석:
1. 클라이언트가 TLS 1.3 미지원
2. 방화벽에서 TLS 1.3 패킷 차단
3. 중간 프록시의 TLS 1.3 미지원

해결 방법:
- 클라이언트 버전 확인 및 업데이트
- 네트워크 장비 펌웨어 업데이트
- TLS 1.2 fallback 설정 유지

문제: 0-RTT 공격 탐지

# 서버 로그에서 의심스러운 0-RTT 패턴 탐지
grep "early_data" /var/log/nginx/access.log | \\
awk '{print $1}' | sort | uniq -c | sort -nr | head -10

# 동일 IP에서 과도한 0-RTT 요청 확인
grep "early_data" /var/log/nginx/access.log | \\
awk '$1=="SUSPICIOUS_IP" {print $4, $7}' | \\
sort | uniq -c

미래 전망과 차세대 보안 프로토콜

Post-Quantum Cryptography 대비

양자 컴퓨터의 위협에 대비한 양자 내성 암호화(Post-Quantum Cryptography) 연구가 활발합니다:

현재 TLS 1.3의 양자 컴퓨터 취약점:

  • RSA, ECDSA 등 현재 공개키 암호화는 양자컴퓨터로 해독 가능
  • 대칭키 암호화(AES)는 키 길이만 늘리면 안전

TLS 1.3의 PQC 준비:

  • 하이브리드 모드: 기존 알고리즘 + 양자 내성 알고리즘 조합
  • 점진적 도입: 기존 시스템과의 호환성 유지
  • 표준화 진행: NIST 표준화 과정 참여

HTTP/3와 QUIC 프로토콜

QUIC + TLS 1.3 통합:

  • 전송계층 통합: UDP 기반으로 더 빠른 연결 설정
  • 0-RTT 기본 제공: 연결 재개시 즉시 데이터 전송
  • 멀티플렉싱: 패킷 손실시에도 다른 스트림에 영향 없음

마무리: TLS 1.3 도입의 필수성

TLS 1.3은 단순한 프로토콜 업그레이드를 넘어 웹 보안과 성능의 패러다임을 바꾼 혁신입니다. TLS 1.3은 가장 빠르고, 가장 최신이며, 가장 안전한 TLS 버전으로, TLS 1.2보다 더 빠르고 안전한 핸드셰이크를 제공합니다.

도입해야 하는 핵심 이유:

🚀 성능 향상

  • 핸드셰이크 시간 50% 단축으로 페이지 로딩 속도 개선
  • 0-RTT로 재연결시 즉시 데이터 전송 가능
  • 모바일 환경에서 배터리 사용량 30% 감소

🛡️ 보안성 강화

  • 취약한 암호화 알고리즘 완전 제거
  • Perfect Forward Secrecy 강제 적용
  • 핸드셰이크 과정 자체도 암호화하여 프라이버시 보호

📈 비즈니스 가치

  • 페이지 로딩 속도 개선으로 전환율 증가
  • 보안 강화로 고객 신뢰도 향상
  • 검색엔진 최적화(SEO) 효과

지금 시작해야 하는 액션 아이템:

  1. 현재 환경 진단: 서버와 클라이언트의 TLS 1.3 지원 현황 확인
  2. 테스트 환경 구축: 스테이징 서버에서 TLS 1.3 적용 및 테스트
  3. 점진적 적용: 프로덕션 환경에 단계적으로 TLS 1.3 도입
  4. 모니터링 체계 구축: 성능 및 보안 지표 지속적 관찰

미래의 웹은 더욱 빨라지고 안전해질 것입니다. TLS 1.3으로의 전환은 선택이 아닌 필수이며, 지금 시작하는 것이 경쟁 우위를 확보하는 길입니다.


참고 자료:

댓글

Designed by JB FACTORY