[Daily morning study] HTTPS와 TLS 핸드셰이크 과정
#daily morning study
HTTPS란
HTTP에 TLS(Transport Layer Security)를 얹은 프로토콜이다. 데이터를 암호화해서 전송하기 때문에 중간에 패킷을 가로채도 내용을 읽을 수 없다. 기본 포트는 443.
TLS는 SSL의 후속 버전이다. SSL 3.0 이후로 명칭이 TLS로 바뀌었고, 지금은 TLS 1.2와 TLS 1.3이 주로 쓰인다. 실무에서 여전히 “SSL 인증서”라고 부르는 경우가 많지만, 실제로는 TLS를 사용한다.
암호화 방식 두 가지
TLS를 이해하려면 대칭키와 비대칭키 암호화를 먼저 알아야 한다.
| 구분 | 대칭키 (Symmetric) | 비대칭키 (Asymmetric) |
|---|---|---|
| 키 개수 | 암호화/복호화에 같은 키 | 공개키(public key) + 개인키(private key) |
| 속도 | 빠름 | 느림 |
| 문제점 | 키를 어떻게 안전하게 공유하느냐 | 느리므로 대용량 데이터에는 부적합 |
| 대표 알고리즘 | AES, ChaCha20 | RSA, ECDH |
TLS 핸드셰이크는 비대칭키로 세션 키(대칭키)를 안전하게 교환하고, 실제 데이터 전송은 그 세션 키로 암호화하는 방식이다.
TLS 1.2 핸드셰이크 과정
Client Server
| |
|-------- ClientHello --------------->|
|<------- ServerHello ----------------|
|<------- Certificate ----------------|
|<------- ServerHelloDone ------------|
| |
|-------- ClientKeyExchange --------->|
|-------- ChangeCipherSpec ---------->|
|-------- Finished ------------------>|
| |
|<------- ChangeCipherSpec -----------|
|<------- Finished -------------------|
| |
|===== 암호화된 데이터 전송 시작 ======|
1. ClientHello 클라이언트가 서버에 연결을 시작하면서 보내는 첫 메시지. 다음 정보를 담는다.
- 지원하는 TLS 버전
- 지원하는 암호화 알고리즘 목록 (Cipher Suite)
- 클라이언트가 생성한 랜덤 값 (Client Random)
2. ServerHello 서버가 ClientHello에 응답. 아래를 선택해서 알려준다.
- 사용할 TLS 버전 (클라이언트가 제시한 것 중 선택)
- 사용할 Cipher Suite
- 서버가 생성한 랜덤 값 (Server Random)
3. Certificate 서버가 자신의 인증서(SSL/TLS 인증서)를 전달한다. 인증서에는 서버의 공개키가 포함되어 있다. 클라이언트는 이 인증서가 신뢰할 수 있는 CA(Certificate Authority)에 의해 서명되었는지 검증한다.
4. ServerHelloDone 서버가 핸드셰이크 메시지 전송을 마쳤다는 신호.
5. ClientKeyExchange 클라이언트가 Pre-Master Secret을 생성하고, 서버의 공개키로 암호화해서 전달한다. 서버는 개인키로 복호화해서 Pre-Master Secret을 얻는다.
이 시점에서 양쪽 모두 아래 세 가지를 가지고 있다.
- Client Random
- Server Random
- Pre-Master Secret
이 세 값을 조합해 Master Secret을 만들고, 여기서 실제 암호화에 쓸 세션 키(Session Key)를 도출한다.
6. ChangeCipherSpec “이제부터 협상한 암호화 방식으로 통신할게요”라는 신호. 클라이언트가 먼저 보내고 서버도 응답한다.
7. Finished 핸드셰이크 내용 전체를 세션 키로 암호화해서 보낸다. 상대방이 정상적으로 복호화하면 핸드셰이크 완료.
TLS 1.3의 개선점
TLS 1.2는 핸드셰이크에 2 RTT(Round Trip Time)가 필요하지만, TLS 1.3은 1 RTT로 줄였다. 재연결 시에는 0 RTT도 가능하다.
주요 변경 사항:
취약한 알고리즘 제거
- RSA 키 교환 방식 제거 (전방 비밀성 미지원)
- MD5, SHA-1 등 구형 해시 알고리즘 제거
- RC4, DES, 3DES 등 취약한 암호화 방식 제거
Forward Secrecy 강제 TLS 1.3은 키 교환에 ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)만 허용한다. 매 세션마다 임시 키를 사용하기 때문에, 나중에 서버의 개인키가 유출되더라도 과거 세션의 데이터는 복호화할 수 없다.
핸드셰이크 비교
| TLS 1.2 | TLS 1.3 | |
|---|---|---|
| 핸드셰이크 RTT | 2 RTT | 1 RTT |
| 재연결 (0-RTT) | 없음 | 지원 |
| 키 교환 | RSA, ECDHE 등 | ECDHE만 허용 |
| Forward Secrecy | 선택 | 필수 |
인증서와 CA (Certificate Authority)
TLS 인증서의 핵심은 신뢰 체계다.
Root CA (최상위 인증기관)
└── Intermediate CA (중간 인증기관)
└── 서버 인증서 (example.com)
브라우저와 OS는 Root CA 목록을 내장하고 있다. 서버 인증서가 중간 CA를 거쳐 신뢰된 Root CA까지 이어지는 체인(Chain of Trust)이 검증되면 신뢰할 수 있는 인증서로 인정한다.
인증서에는 다음 정보가 포함된다.
- 도메인 이름 (Common Name / SAN)
- 공개키
- 유효 기간
- 발급 CA 정보
- CA의 서명
HTTPS 적용 시 확인할 것
Mixed Content 문제 HTTPS 페이지에서 HTTP 리소스(이미지, 스크립트 등)를 불러오면 브라우저가 차단하거나 경고를 띄운다. 모든 리소스를 HTTPS로 제공해야 한다.
HSTS (HTTP Strict Transport Security) 서버가 Strict-Transport-Security 헤더를 내려보내면, 브라우저는 해당 도메인에 대해 이후 요청을 무조건 HTTPS로 보낸다. HTTP로 접근하려고 해도 브라우저가 자동으로 HTTPS로 바꿔준다.
Strict-Transport-Security: max-age=31536000; includeSubDomains
인증서 만료 모니터링 인증서는 유효 기간이 있다. 만료되면 브라우저에서 경고를 띄우고 사용자가 접근하지 못하게 된다. Let’s Encrypt 같은 무료 CA는 90일마다 갱신이 필요하다. 자동 갱신 설정을 권장한다.
정리
- HTTPS = HTTP + TLS 암호화
- TLS 핸드셰이크는 비대칭키로 세션 키를 교환하고, 이후 데이터는 대칭키로 암호화
- TLS 1.3은 1 RTT, Forward Secrecy 강제, 취약 알고리즘 제거로 보안성과 성능 모두 향상
- 인증서는 CA 체인으로 신뢰를 검증하며, 만료 전 갱신 관리 필수