전송 구간을 암호화하고 상대의 신원을 확인하는 보안 계층(Transport Layer Security). HTTPS는 그냥 "HTTP를 TLS 위에 올린 것"이다. SSL은 TLS의 옛 이름이다.
무엇을 보장하나
| 목표 | 수단 |
|---|---|
| 기밀성 — 못 훔쳐본다 | 대칭키 암호화 |
| 무결성 — 못 바꾼다 | MAC(메시지 인증 코드) |
| 인증 — 상대가 진짜다 | 인증서 + 공개키 서명 |
왜 대칭키와 공개키를 섞어 쓰나
- 대칭키(같은 키로 잠그고 열기) — 빠르다. 그런데 키를 어떻게 안전하게 나누지?
- 공개키(공개키로 잠그고 개인키로 열기) — 키 배포 문제가 없다. 그런데 느리다 (수백~수천 배).
그래서 공개키로 대칭키를 안전하게 합의하고, 실제 데이터는 대칭키로 주고받는다. 이것을 하이브리드 암호화라 한다.
핸드셰이크 (TLS 1.2 기준)
클라 ─── ClientHello ──────────► 지원 암호 목록 + 난수
클라 ◄── ServerHello ─────────── 선택한 암호 + 난수
클라 ◄── Certificate ─────────── 서버 인증서(공개키 + CA 서명)
클라 ◄── ServerHelloDone ───────
│ ① CA 체인 검증 → 서버 신원 확인
│ ② 키 교환(ECDHE) → 양쪽이 같은 세션 키 도출
클라 ─── ChangeCipherSpec ─────► "이제부터 암호화한다"
클라 ◄── ChangeCipherSpec ──────
암호화된 통신 시작
인증서가 하는 일 — 오해가 많다
인증서는 암호화 도구가 아니다. "이 공개키가 정말 example.com의 것"임을
CA(인증기관)가 자기 개인키로 서명해 보증하는 문서다.
브라우저는 OS·브라우저에 미리 심어 둔 루트 CA 목록으로 서명 체인을 검증한다. 자체 서명 인증서는 암호화는 되지만 보증해 줄 CA가 없어 경고가 뜬다.
중간자 공격을 어떻게 막나
공격자가 중간에서 자기 공개키를 내밀어도, 그 키에 대한 믿을 수 있는 CA의 서명을 만들 수 없다. 검증에서 걸린다. 사내 프록시가 통신을 열어 보려면 자체 CA를 단말에 설치해야 하는 이유가 이것이다.
TLS 1.3에서 달라진 것
- 핸드셰이크가 2-RTT → 1-RTT로 단축, 재연결은 0-RTT 가능
- 취약한 것들을 제거 — RSA 키 교환(순방향 비밀성 없음), CBC 모드, SHA-1, 압축
- 순방향 비밀성(PFS) 필수 — 서버 개인키가 나중에 유출돼도 과거 트래픽은 못 푼다
0-RTT의 대가
재전송 공격에 취약하다. 공격자가 0-RTT 데이터를 그대로 다시 보내면 서버가 두 번 처리할 수 있다. 그래서 멱등한 요청(GET)에만 쓰는 것이 원칙이다.