| 일 | 월 | 화 | 수 | 목 | 금 | 토 |
|---|---|---|---|---|---|---|
| 1 | 2 | 3 | 4 | |||
| 5 | 6 | 7 | 8 | 9 | 10 | 11 |
| 12 | 13 | 14 | 15 | 16 | 17 | 18 |
| 19 | 20 | 21 | 22 | 23 | 24 | 25 |
| 26 | 27 | 28 | 29 | 30 | 31 |
- LLM
- RDS
- 오블완
- Kubernetes
- MCP
- 클로드코드
- GoF
- https
- claude code
- Infra
- typescript
- AWS
- 구조체
- golang
- Harness Engineering
- 티스토리챌린지
- AI
- ai agent
- GIT
- MSA
- EKS
- OpenClaw
- elasticsearch
- go
- DB
- Intellij
- goland
- logging
- TLS
- esbuild
- Today
- Total
Fall in IT.
HTTPS는 어떻게 연결되는가: 인증서 발급부터 암호화 통신까지 본문
브라우저 주소창의 자물쇠는 두 단계를 거쳐 켜진다. 서버가 인증기관에서 인증서를 발급받는 단계와, 브라우저가 접속할 때 그 인증서로 암호화 통신을 여는 단계다. 이 글은 두 단계에서 무엇이 오가는지 순서대로 정리한다. 필요한 준비물, 알아야 할 개념, 실제 통신 순서가 차례로 나온다.
1. 전체 그림 먼저
HTTPS 통신이 성립하는 과정을 세 문장으로 줄이면 이렇다.
"서버는 브라우저가 신뢰할 수 있는 인증서를 발급받는다."
"브라우저는 접속할 때 그 인증서를 검증하고, 세션키를 만들어 인증서에 담긴 공개키로 암호화해 보낸다."
"서버가 개인키로 세션키를 꺼내면 이후 모든 통신은 대칭키인 세션키로 암호화된다."
앞의 한 문장은 사용자가 접속하기 전에 끝나 있어야 하는 준비 작업이다. 뒤의 두 문장은 연결이 맺어질 때마다 반복된다. 이 구분이 이 글의 목차이기도 하다.
남은 것은 세 가지 질문이다. 무엇이 필요한가. 어떤 개념을 알아야 하는가. 어떤 순서로 무엇이 오가는가.
2. 인증서란 무엇이고 누가 무엇을 하는가
인증서(Certificate)는 이 공개키가 이 도메인의 것임을 인증기관이 서명해 보증한 문서다. 비밀을 나르는 통로가 아니라 신원을 증명하는 서명이라는 점이 출발점이다.
등장인물은 셋이다.
브라우저는 상대를 믿어도 되는지 판단한다.
서버는 자신이 그 도메인의 주인임을 증명한다.
인증기관(CA, Certificate Authority)은 그 증명을 대신 보증한다.
이 글에서는 브라우저를 Chrome, 서버를 Spring Boot, CA를 무료 인증서를 발급하는 Let's Encrypt로 둔다.
브라우저가 서버를 직접 검증할 방법은 없다. 처음 보는 서버다. 그래서 신뢰를 위임한다. 브라우저와 운영체제는 신뢰하는 CA 목록을 미리 갖고 있고, 그 목록에 있는 CA가 서명한 인증서라면 받아들인다.
공개키와 개인키
인증서를 이해하려면 키 두 개를 먼저 봐야 한다. 공개키(Public Key)와 개인키(Private Key)는 수학적으로 짝을 이루는 한 쌍이며 서로를 대신할 수 없다.
자물쇠에 비유하면 공개키는 자물쇠이고 개인키는 열쇠다. 자물쇠는 누구에게나 나눠줄 수 있다. 누구나 그것으로 잠글 수 있지만 열 수 있는 쪽은 열쇠를 가진 하나뿐이다. 공개키를 인증서에 담아 전 세계에 뿌려도 안전한 이유가 여기에 있다.
다만 이 비유는 개인키의 다른 쓰임을 설명하지 못한다. 자물쇠는 잠그기만 하지만 개인키는 잠긴 것을 여는 동시에 문서에 도장을 찍는 데도 쓰인다. 개인키로 서명하면 짝이 되는 공개키로 그 서명이 진짜인지 검증할 수 있다. 뒤에 나올 CA의 전자서명과 TLS 1.3의 키 교환이 모두 이 성질에 기댄다.
CA는 키를 발급하지 않는다
흔한 오해가 하나 있다. Let's Encrypt가 공개키와 개인키를 만들어 준다는 생각이다.
순서는 반대다. 키 페어를 만드는 쪽은 서버다. ACME 클라이언트가 서버에서 공개키와 개인키를 생성하고, 공개키와 도메인 이름을 CA에 보낸다. CA가 돌려주는 것은 "이 공개키는 abc.com의 것이다"라고 서명한 인증서 하나뿐이다.
이 설계에는 이유가 있다. 개인키가 한 번도 네트워크를 타지 않으면 중간에서 가로챌 방법도 없다. CA가 침해를 당해도 서버의 개인키는 그곳에 없다. 개인키는 서버를 떠나지 않는다는 원칙이 HTTPS 운영의 첫 번째 규칙이다.
인증서에는 도메인 이름, 공개키, 유효기간, 발급기관, 그리고 이 내용 전체에 대한 CA의 전자서명이 담긴다. 브라우저는 그 서명을 검증해 내용이 위조되지 않았음을 확인한다.
3. 준비물과 두 단계 프로세스
HTTPS 적용은 두 단계로 나뉜다. 사용자가 접속하기 전에 인증서를 준비하는 단계와, 접속할 때마다 그 인증서로 통신을 여는 단계다. 앞 단계는 며칠에 한 번 일어나고 뒤 단계는 연결마다 일어난다.
준비물 네 가지
필요한 것은 도메인, DNS 설정, 서버 제어 권한, ACME 클라이언트다.
네 가지가 각각 왜 필요한지는 하나의 목적으로 묶인다. CA는 신청자가 그 도메인을 통제한다는 증거만 본다. 도메인이 있어야 증명할 대상이 생기고, DNS가 서버를 가리켜야 CA가 확인하러 올 수 있으며, 서버에 파일을 만들거나 DNS 레코드를 고칠 수 있어야 증거를 남길 수 있다. ACME(Automated Certificate Management Environment)는 이 절차를 자동화한 프로토콜이고 Certbot과 cert-manager가 대표적인 클라이언트다.
도메인이 없으면 발급받을 수 없다는 통념에는 예외가 생겼다. Let's Encrypt는 2026년 1월 15일부터 IP 주소를 대상으로 한 인증서를 정식 제공한다. 다만 유효기간이 6일인 단기 프로파일에 한정되므로 자동화가 전제된다.
1단계. 인증서 발급
sequenceDiagram
participant S as 서버
participant CA as Let's Encrypt
S->>S: 키 페어 생성
S->>CA: abc.com 인증서 요청 · 공개키 전달
CA->>S: 도메인 통제 증명 요구 · 토큰 발급
S->>S: .well-known/acme-challenge 아래 토큰 파일 생성
CA->>S: 인터넷에서 직접 접속해 토큰 확인
S-->>CA: 토큰 응답
CA->>S: 서명된 인증서 발급
Note over S: 개인키는 서버를 떠나지 않는다
위 그림에서 볼 것은 마지막 확인의 방향이다. 서버가 증거를 보내는 것이 아니라 CA가 서버로 직접 들어온다.
서버에서 certbot certonly -d abc.com을 실행하면 대화가 시작된다. CA는 바로 발급하지 않고 도메인을 통제하는지 묻는다. Certbot이 /.well-known/acme-challenge/ 아래에 토큰 파일을 만들면, CA가 인터넷에서 그 주소로 접속해 확인한 뒤 서명된 인증서를 내려준다.
여기서 CA가 확인한 것을 정확히 볼 필요가 있다. 확인된 것은 도메인의 법적 소유권이 아니다. 지금 그 도메인의 요청에 응답하는 서버를 조작할 수 있다는 통제권이다. 그래서 DNS를 탈취당하면 남이 내 도메인으로 인증서를 받을 수 있고, CAA 레코드처럼 발급 가능한 CA를 도메인 쪽에서 제한하는 장치가 존재한다.
이 방식은 HTTP-01 검증이라 부른다. 검증은 80 포트에서 시작한다. 리다이렉트는 따라가므로 HTTPS 강제 리다이렉트 자체는 문제가 되지 않지만, 80 포트를 방화벽에서 닫아두면 발급이 실패한다.
발급 후 남는 네 개의 파일
파일 담긴 것 쓰임
| cert.pem | 내 도메인 인증서 하나 | 단독으로 설정하면 체인이 빠진다 |
| chain.pem | 중간 인증서 | 내 인증서와 루트를 잇는 사슬 |
| fullchain.pem | cert.pem + chain.pem | 서버에 설정하는 파일 |
| privkey.pem | 개인키 | 서버만 보관하며 밖으로 내보내지 않는다 |
브라우저가 신뢰 목록에 갖고 있는 것은 루트 인증서뿐이다. 내 인증서에서 루트까지 이어지는 사슬은 서버가 제시해야 한다. 그래서 서버에 설정하는 파일은 fullchain.pem이다.
cert.pem만 설정하면 문제가 즉시 드러나지 않는다. 중간 인증서를 이미 확보한 클라이언트는 사슬을 스스로 이어 통과하고, 그렇지 않은 클라이언트는 검증에 실패한다. 같은 서버가 클라이언트에 따라 다르게 동작하는 이유가 여기에 있다.
2단계. 브라우저 접속
sequenceDiagram
participant B as 브라우저
participant D as DNS
participant S as 서버
B->>D: abc.com 주소 조회
D-->>B: 123.123.123.123
B->>S: 443 포트로 TLS 연결 시작
S-->>B: 인증서 제시 · fullchain.pem
B->>B: 체인 서명 · 도메인 · 유효기간 검증
B->>B: 세션키 생성
B->>S: 공개키로 암호화한 세션키 전송
S->>S: 개인키로 복호화
Note over B,S: 이후 모든 요청과 응답은 세션키로 암호화
브라우저에 https://abc.com을 입력하면 먼저 DNS 조회가 일어난다. 도메인이 IP 주소로 바뀌고 브라우저는 그 주소의 443 포트로 연결한다.
서버는 fullchain.pem을 제시한다. 브라우저는 세 가지를 확인한다. 서명 사슬이 신뢰하는 루트까지 이어지는가, 접속하려던 도메인이 인증서에 적힌 도메인과 일치하는가, 유효기간이 남아 있는가. 하나라도 어긋나면 경고 화면을 띄우고 연결을 멈춘다.
검증을 통과하면 브라우저는 이번 연결에서만 쓸 세션키(Session Key)를 만든다. 대칭키, 즉 잠그는 키와 여는 키가 같은 방식의 키다. 브라우저는 인증서에 담긴 공개키로 이 세션키를 암호화해 서버에 보낸다. 서버는 privkey.pem의 개인키로 그것을 복호화한다.
이 지점이 HTTPS의 핵심이다. 세션키는 공개된 네트워크를 지나갔지만 잠긴 상태였고, 열 수 있는 개인키는 서버에만 있다. 중간에서 가로챈 쪽은 암호문만 갖는다. 이제 브라우저와 서버는 같은 세션키를 갖고 있고, GET /users 같은 요청과 응답은 모두 그 키로 암호화된다.
왜 공개키로 계속 통신하지 않는가
공개키 방식은 편리하지만 연산 비용이 크다. 모든 요청과 응답을 공개키로 처리하면 통신이 안전해지기 전에 서버 CPU가 먼저 한계에 닿는다.
그래서 HTTPS는 역할을 나눈다. 느리고 비싼 공개키 방식은 세션키 하나를 안전하게 합의하는 데만 쓰고, 실제 데이터는 AES 같은 빠른 대칭키 방식으로 나른다. 비대칭과 대칭을 섞어 쓰는 이 구조를 하이브리드 암호라 부른다.
보완. TLS 1.3에서 달라진 것
위에서 설명한 흐름은 TLS 1.2에서 널리 쓰인 RSA 키 교환 모델이다. 원리를 이해하기에 가장 명확한 그림이지만, 현재 Chrome과 최신 서버가 실제로 맺는 연결과는 차이가 있다.
TLS 1.3은 이 방식을 제거하고 ECDHE(Elliptic Curve Diffie-Hellman Ephemeral)를 쓴다. 브라우저가 세션키를 만들어 암호화해 보내는 대신, 양쪽이 각자 일부 정보를 교환해 같은 세션키를 각자 계산한다. 세션키가 네트워크를 흐르지 않으므로, 서버 개인키가 나중에 유출되더라도 지난 트래픽을 되돌려 복호화할 수 없다. 이 성질을 전방 비밀성(Forward Secrecy)이라 한다.
방식이 달라져도 세 역할은 그대로다. 인증서는 서버의 신원을 증명하고, 개인키는 그 신원의 증거이면서 키 교환에 서명하고, 세션키는 실제 데이터를 빠르게 암호화한다. 이 셋을 붙잡고 있으면 어느 버전을 보든 구조는 읽힌다.
4. HTTPS가 요구하는 대가
얻는 것 잃는 것 대가의 형태
| 도청과 위조 차단 | 갱신 자동화라는 상시 운영 부담 | 갱신 실패는 성능 저하가 아니라 전면 차단이다 |
| 제3자가 보증하는 서버 신원 | 개인키 보관 지점 관리 | 개인키가 유출되면 폐기해도 즉시 무력화되지 않는다 |
| 무료 CA와 자동화 도구 | TLS 종료 위치라는 아키텍처 결정 | 위치를 잘못 잡으면 갱신마다 애플리케이션을 재시작해야 한다 |
가장 큰 비용은 암호 기술이 아니라 유효기간이다. 그리고 유효기간은 짧아지는 방향으로 움직인다.
CA/Browser Forum은 2025년 4월 공개 TLS 인증서의 최대 유효기간을 단계적으로 줄이는 안을 가결했다. 2026년 3월 15일부터 200일, 2027년 3월 15일부터 100일, 2029년 3월 15일부터 47일이다. 첫 단계는 이미 적용 중이다. Let's Encrypt는 기본 90일을 유지하면서 2026년 1월 15일부터 6일 유효기간의 단기 인증서를 정식 제공한다. 선택 항목이며 기본값은 아니다.
이 흐름은 폐기(revocation)가 제대로 동작하지 않는다는 현실을 인정한 결과다. 유출된 인증서를 취소해도 그 정보가 모든 브라우저에 제때 닿지 않는다. Let's Encrypt는 2025년 8월 6일 OCSP 응답 서비스를 종료하고 CRL만 남겼다. 실시간 폐기 확인이 사실상 사라진 자리를 짧은 유효기간이 대신한다. 인증서를 취소하는 대신 빨리 만료시키는 쪽으로 방향이 잡힌 것이다.
여기에 하나가 더 겹친다. Let's Encrypt는 2025년 6월 4일 인증서 만료 알림 메일을 중단했다. 갱신이 밀리고 있다는 사실을 알려줄 사람은 이제 없다. 갱신은 사람이 기억하는 일이 아니라 시스템이 보장하는 일이 됐고, 그 보장을 스스로 감시해야 한다.
5. 어떤 방식을 언제 쓰고 언제 쓰지 않는가
HTTPS 자체는 선택 사항이 아니다. 선택은 방식에서 갈린다.
검증 방식은 두 가지가 있다. HTTP-01은 서버에 파일을 놓는 방식이고 설정이 단순하지만 80 포트가 외부에 열려 있어야 하며 와일드카드 인증서를 받을 수 없다. DNS-01은 DNS에 TXT 레코드를 놓는 방식이고 DNS API 권한이 필요한 대신 외부에서 접근할 수 없는 내부 도메인과 와일드카드를 처리할 수 있다.
클라이언트는 실행 환경으로 갈린다. 단일 서버나 VM은 Certbot과 스케줄러로 충분하고, 쿠버네티스는 cert-manager가 인증서를 리소스로 다루므로 갱신과 배포가 한 흐름에 들어온다.
가장 결과가 크게 갈리는 선택은 TLS를 어디서 끊는지다. 애플리케이션에서 직접 끊으면 구성이 단순해 보이지만 인증서가 애플리케이션의 배포 주기에 묶인다. 리버스 프록시나 로드밸런서에서 끊으면 인증서 갱신과 애플리케이션 배포가 분리되고, 개인키를 두는 지점도 한 곳으로 모인다.
쓰지 말아야 할 조건은 분명하다.
- 자동 갱신 없이 수동 발급으로 버티기. 유효기간 단축 일정이 이 선택지를 없앴다. 200일도 손으로 관리할 주기가 아니며 100일과 47일에서는 불가능하다.
- 앞단에 프록시나 로드밸런서가 있는데 애플리케이션에 인증서를 넣기. 갱신마다 애플리케이션을 재시작해야 하고 개인키 보관 지점이 늘어난다. 앞단에서 이미 TLS를 끊을 수 있다면 그렇게 한다.
- 내부 도메인이나 와일드카드가 필요한데 HTTP-01을 고집하기. 구조적으로 통과할 수 없는 검증을 붙들고 시간을 쓰게 된다.
설계를 점검할 때는 세 가지를 묻는다. TLS를 어디서 끊는가. 갱신 실패를 무엇이 알려주는가. 개인키가 몇 군데 존재하는가.
6. 정리
인증서는 비밀을 나르는 통로가 아니라 "이 공개키는 이 도메인의 것"이라는 CA의 서명이다.
개인키는 서버를 떠나지 않고, 브라우저와 서버가 합의한 세션키가 실제 데이터를 암호화한다.
HTTPS 적용은 인증서를 준비하는 단계와 그 인증서로 통신을 여는 단계로 나뉜다. 문제가 생겼을 때는 두 단계 중 어디서 끊겼는지부터 구분한다.
암호 알고리즘은 이미 검증된 부분이고, 유효기간이 짧아지는 흐름에서 운영 부담이 집중되는 곳은 갱신 자동화다.
참고 자료
- Ballot SC-081v3: Introduce Schedule of Reducing Validity and Data Reuse Periods, CA/Browser Forum
- 6-day and IP Address Certificates are Generally Available, Let's Encrypt
- Ending OCSP Support in 2025, Let's Encrypt
- Let's Encrypt to cease expiration notification emails in June 2025
- RFC 8446: The Transport Layer Security (TLS) Protocol Version 1.3
'기타' 카테고리의 다른 글
| 요청을 받는 사람과 문제를 다시 쓰는 사람: BRM이 일하는 방식 (0) | 2026.06.11 |
|---|---|
| [제약/바이오 IT] ERP와 EBR의 데이터 인터페이스: SAP PO와 PP 모듈의 이해 (0) | 2026.03.05 |
| 노르웨이의 숲을 읽고 (0) | 2025.12.31 |
| 2FA와 TOTP 기반 OTP 인증 시스템의 이해 (0) | 2025.12.19 |
| 연차는 쌓이는데, 왜 실력은 제자리일까? (0) | 2025.09.06 |
