HTTPS 보안의 실체: 자물쇠 아이콘이 보장하는 것과 80%가 모르는 것
HTTPS 자물쇠 아이콘이 보장하는 것과 보장하지 못하는 것. 피싱 사이트의 80%도 HTTPS를 사용한다. SSL Stripping부터 CA 침해까지.
HTTPS 자물쇠 아이콘이 보장하는 것과 보장하지 못하는 것. 피싱 사이트의 80%도 HTTPS를 사용한다. SSL Stripping부터 CA 침해까지.
[브라우저 주소창의 자물쇠 아이콘을 보면 안심한다. 그런데 피싱 사이트의 82%도 HTTPS를 사용한다(Anti-Phishing Working Group, 2025). 자물쇠가 보장하는 것과 보장하지 않는 것의 차이를 모르면, 보안의 착각 속에 있는 것이다.
HTTP의 세 가지 근본 취약점은 도청(제3자가 내용을 읽음), 변조(전송 중 데이터 수정), 사칭(서버 신원 미확인)이다. 이 취약점을 악용하는 공격 기법은 TLS 핸드셰이크의 단계별 상세 분석은 시리즈 다음 글에서 다룬다.
TLS 1.3 핸드셰이크 흐름
HTTPS는 HTTP 통신을 TLS(Transport Layer Security) 프로토콜로 감싸서 기밀성, 무결성, 인증 세 가지를 보장하는 프로토콜이다.
"HTTP over TLS provides security services: server identification, data confidentiality, and data integrity." — RFC 2818, Section 1
RFC 2818을 풀어보면, HTTPS는 HTTP 자체를 바꾸는 것이 아니다. 기존 HTTP 메시지를 TLS라는 암호화 터널 안에서 주고받는 것이다. 브라우저 주소창의 자물쇠 아이콘은 이 터널이 설정되었다는 표시다.
| 보장 | 설명 |
|---|---|
| 기밀성(Confidentiality) | 통신 내용을 제3자가 읽을 수 없다. 세션 쿠키, 비밀번호, 개인정보가 암호화된다 |
| 무결성(Integrity) | 전송 중 데이터가 변조되지 않았음을 검증한다. ISP가 광고를 삽입하거나 공격자가 응답을 수정할 수 없다 |
| 인증(Authentication) | 접속한 서버가 실제로 그 도메인의 소유자인지 인증서로 확인한다 |
비유하면, HTTP는 엽서다. 배달 과정에서 누구나 읽을 수 있고, 내용을 바꿀 수 있고, 보낸 사람을 확인할 수 없다. HTTPS는 봉투에 넣고 봉인한 등기우편이다. 내용을 읽을 수 없고, 뜯으면 티가 나고, 발신자를 확인할 수 있다.
| 용어 | 역할 |
|---|---|
| SSL | TLS의 전신. SSL 3.0까지 존재했으나 보안 취약점으로 폐기. 여전히 "SSL 인증서"라는 이름이 관행적으로 사용됨 |
| TLS | SSL을 대체한 현행 표준. TLS 1.2와 1.3이 현재 권장 버전 |
| HTTPS | HTTP + TLS 조합. 프로토콜 자체가 아니라 HTTP를 TLS 위에서 사용하는 방식 |
| 인증서 | 서버의 신원을 증명하는 디지털 문서. CA(Certificate Authority)가 발급 |
HTTPS의 핵심은 디지털 인증서(X.509)다. 인증서는 서버가 "나는 revelare.kr의 합법적 소유자다"라고 증명하는 디지털 문서다.
인증서에 포함되는 핵심 정보는 다음과 같다.
# X.509 인증서의 주요 필드
발급 대상(Subject): revelare.kr
발급자(Issuer): Let's Encrypt Authority X3
유효 기간: 2026-01-01 ~ 2026-03-31
공개 키: RSA 2048-bit 또는 ECDSA P-256
서명 알고리즘: SHA-256
인증서 체인: Root CA → Intermediate CA → Server Certificate
여기서 중요한 것은 인증서 체인(Certificate Chain)이다. 브라우저는 서버 인증서를 바로 신뢰하지 않는다. 대신 다음 경로를 따라 검증한다.
서버 인증서 → 이것을 서명한 중간 CA 인증서 → 이것을 서명한 루트 CA 인증서
루트 CA는 운영체제와 브라우저에 미리 내장되어 있다. Windows, macOS, Android, iOS 모두 신뢰하는 루트 CA 목록을 관리한다. 이 목록에 없는 CA가 발급한 인증서는 브라우저가 경고를 표시한다.
그런데 2015년, 이 구조에 중요한 변화가 생겼다.
Let's Encrypt가 무료 인증서 발급을 시작한 것이다. 기존에는 인증서 하나에 연간 수십~수백 달러가 들었다. Let's Encrypt는 자동화된 검증 프로세스(ACME 프로토콜)로 무료 인증서를 제공하며, 2020년 2월까지 10억 건의 인증서를 발급했다. 전 세계 HTTPS 페이지 로드 비율은 2017년 58%에서 현재 80% 이상으로 증가했다.
브라우저가 https://revelare.kr에 접속하면 데이터를 주고받기 전에 TLS 핸드셰이크가 일어난다. 이 과정에서 서버 인증서를 검증하고, 양쪽이 사용할 암호화 키를 합의한다.
# TLS 1.3 핸드셰이크 개요 (1-RTT)
[클라이언트] [서버]
| |
|--- ClientHello ------------->| # 지원하는 암호 목록 + 키 공유
| |
|<-- ServerHello + 인증서 -----| # 선택한 암호 + 인증서 + 키 공유
| |
|--- Finished ---------------->| # 인증서 검증 완료, 암호화 시작
| |
|<========= 암호화된 HTTP ========>|
TLS 1.3은 이전 버전(1.2)보다 핸드셰이크를 단순화했다. 1-RTT(한 번의 왕복)만으로 연결을 수립한다. 각 단계에서 어떤 암호화 알고리즘이 협상되고, 키 교환이 어떻게 이루어지는지는 시리즈 다음 글 "TLS/SSL 심층 분석"에서 상세히 다룬다.
브라우저가 서버로부터 인증서를 받으면 다음을 순서대로 확인한다.
1단계 — 체인 검증: 서버 인증서 → 중간 CA → 루트 CA까지의 서명 체인이 유효한가? 루트 CA가 브라우저의 신뢰 목록에 있는가?
2단계 — 도메인 일치: 인증서의 Subject Alternative Name(SAN) 필드에 현재 접속 중인 도메인이 포함되어 있는가?
3단계 — 유효 기간: 인증서가 만료되지 않았는가?
4단계 — 폐기 확인: 인증서가 폐기(revoke)되지 않았는가? 이를 확인하는 두 가지 방법이 있다.
| 방식 | 설명 |
|---|---|
| CRL (Certificate Revocation List) | CA가 폐기된 인증서 목록을 공개. 목록이 커지면 다운로드 부담 |
| OCSP (Online Certificate Status Protocol) | 특정 인증서의 상태만 실시간 조회. CRL보다 효율적이나 CA 서버 가용성에 의존 |
최근에는 OCSP Stapling 방식이 널리 사용된다. 서버가 CA에서 미리 OCSP 응답을 받아두고, TLS 핸드셰이크 시 함께 전달한다. 브라우저가 직접 CA에 연결할 필요가 없어 속도와 프라이버시 모두 개선된다.
HTTPS가 설정된 서버에 HTTP로 접속하면 어떻게 될까? 대부분의 서버는 301 리다이렉트로 HTTPS로 보낸다.
# HTTP 요청
GET / HTTP/1.1
Host: revelare.kr
# 서버 응답 — HTTPS로 리다이렉트
HTTP/1.1 301 Moved Permanently
Location: https://revelare.kr/
문제는 첫 번째 HTTP 요청은 평문이라는 점이다. 이 짧은 순간에 공격자가 끼어들 수 있다. 이것이 SSL Stripping 공격의 핵심이며, 뒤의 보안 관점 섹션에서 자세히 다룬다.
이를 방어하는 것이 HSTS(HTTP Strict Transport Security)다.
# 서버가 HSTS 헤더를 설정
Strict-Transport-Security: max-age=31536000; includeSubDomains; preload
이 헤더를 한 번 받은 브라우저는 max-age 기간(위 예시에서 1년) 동안 해당 도메인에 HTTP 요청 자체를 보내지 않는다. http://revelare.kr을 입력해도 브라우저가 내부적으로 https://로 변환한 후 요청한다. 서버에 연결하기 전에 브라우저 단에서 처리되므로 중간자가 개입할 여지가 없다.
그런데 HSTS에도 한계가 있다. 사용자가 처음 방문할 때는 HSTS 헤더를 아직 받지 못한 상태다. 이 첫 방문 문제를 해결하는 것이 HSTS Preload List다. 구글이 관리하는 이 목록에 도메인을 등록하면, Chrome, Firefox, Safari, Edge 등 주요 브라우저가 처음부터 HTTPS만 사용한다.
인증서 체계의 또 다른 안전장치로 Certificate Transparency(CT)가 있다. CT는 CA가 인증서를 발급할 때마다 공개 로그에 기록하도록 강제하는 프레임워크다.
도메인 소유자는 CT 로그를 모니터링하여 자신의 도메인에 대해 발급된 모든 인증서를 확인할 수 있다. 누군가 revelare.kr에 대한 인증서를 무단으로 발급받으면 로그에서 즉시 감지된다. Google Chrome은 2018년 4월부터 CT 로그에 등록되지 않은 인증서를 신뢰하지 않는다.
인증서 체인 검증 구조
HTTPS가 도청, 변조, 사칭을 막는다면, 공격자는 어떤 약점을 노릴까. HTTPS의 공격 표면은 "암호화 자체"가 아니라 암호화 전후의 과정에 존재한다.
2009년 Black Hat DC에서 모시 마를린스파이크(Moxie Marlinspike)가 sslstrip도구를 발표했다. 원리는 간단하다.
공격자는 같은 네트워크에서 중간자 위치를 확보한다(ARP 스푸핑 등). 그리고 클라이언트와 서버 사이에서 다음을 수행한다.
클라이언트 ← HTTP → 공격자 ← HTTPS → 서버
클라이언트가 http://bank.com에 접속하면, 서버는 https://bank.com으로 리다이렉트한다. 하지만 공격자가 이 리다이렉트를 가로채고, 자신은 서버와 HTTPS로 통신하면서 클라이언트에게는 HTTP로 응답을 전달한다. 클라이언트는 주소창에 https://가 아닌 http://가 표시되지만, 대부분의 사용자는 이를 인지하지 못한다.
방어: HSTS가 이 공격을 차단한다. HSTS Preload List에 등록된 도메인은 브라우저가 HTTP 연결 자체를 시도하지 않으므로 sslstrip이 개입할 여지가 없다.
HTTPS 페이지가 HTTP로 리소스를 로드하면 Mixed Content 문제가 발생한다.
<script src="http://cdn.example.com/app.js"></script>
<img src="http://cdn.example.com/logo.png">
브라우저는 Mixed Content를 두 종류로 구분한다.
| 구분 | 차단 여부 |
|---|---|
| Active Mixed Content (스크립트, 스타일시트, iframe) | 브라우저가 즉시 차단. 스크립트가 변조되면 페이지 전체를 장악할 수 있기 때문 |
| Passive Mixed Content (이미지, 오디오, 비디오) | 최신 브라우저는 자동으로 HTTPS로 업그레이드 시도. 실패하면 차단 |
현재 Chrome, Firefox, Safari 모두 Active Mixed Content를 기본 차단한다. 공격자가 HTTP로 전달되는 JavaScript 파일을 변조하면 HTTPS 페이지의 모든 보안이 무의미해지기 때문이다.
참고: 2020년부터 Chrome은 HTTP 리소스를 자동으로 HTTPS로 업그레이드하는 정책을 단계적으로 적용하고 있으며, Firefox도 동일한 방향으로 이동했다.
HTTPS의 인증 체계는 "CA를 신뢰한다" 는 전제 위에 서 있다. CA가 침해되면 이 전제가 무너진다.
사례 1: Comodo 침해 (2011년 3월)
2011년 3월 15일, Comodo의 등록 기관(RA) 계정이 침해되어 9개의 위조 인증서가 발급됐다. 대상은 Google, Yahoo, Microsoft, Mozilla, Skype의 도메인이었다. 공격자의 IP는 이란으로 추적됐으며, 위조된 login.yahoo.com 인증서가 이란의 웹서버에서 실제로 사용된 것이 확인됐다.
사례 2: DigiNotar 침해 (2011년 7월~8월)
네덜란드의 인증 기관 DigiNotar는 더 심각했다. 공격자가 CA 서버 8대 전체를 장악하고, *.google.com 와일드카드 인증서를 위조 발급했다. 이 인증서는 약 30만 명의 이란 Gmail 사용자에 대한 중간자 공격(MITM)에 사용됐다. 조사 결과 공격자의 흔적은 이란을 가리켰다.
모든 주요 브라우저가 DigiNotar의 루트 인증서를 신뢰 목록에서 제거했고, DigiNotar는 파산했다.
이 두 사건이 남긴 교훈은 명확하다. HTTPS의 보안은 CA의 보안만큼만 강하다. CA 하나가 침해되면 해당 CA가 발급한 모든 인증서의 신뢰가 훼손된다. 이 문제를 완화하기 위해 Certificate Transparency, CAA(Certificate Authority Authorization) 레코드 등의 기술이 도입됐다.
Let's Encrypt 덕분에 누구나 무료로 HTTPS 인증서를 받을 수 있게 됐다. 이는 좋은 일이지만, 부작용도 있다.
공격자도 피싱 사이트에 HTTPS를 적용할 수 있다. https://g00gle-login.com같은 도메인에 유효한 인증서를 발급받으면, 브라우저는 자물쇠 아이콘을 표시한다.
자물쇠 아이콘 = "이 연결은 암호화되어 있다"
자물쇠가 보장하지 않는 것은 다음과 같다.
| 보장하는 것 | 보장하지 않는 것 |
|---|---|
| 통신 내용이 암호화됨 | 사이트 운영자가 신뢰할 수 있는 사람인지 |
| 전송 중 데이터가 변조되지 않음 | 서버에 저장된 데이터가 안전한지 |
| 접속한 도메인이 인증서와 일치함 | 그 도메인 자체가 정당한 사이트인지 |
TLS 핸드셰이크에는 보안상 알려진 한계가 하나 있다. SNI(Server Name Indication)이다.
한 IP 주소에 여러 도메인이 호스팅되는 경우(가상 호스팅), 클라이언트는 TLS 핸드셰이크 시 접속하려는 도메인명을 평문으로 전달해야 한다. 서버가 올바른 인증서를 선택하려면 도메인명을 알아야 하기 때문이다.
# ClientHello의 SNI 필드 (평문)
Extension: server_name
Server Name: revelare.kr ← 네트워크 감시자가 확인 가능
이는 통신 내용은 암호화되지만, 어떤 사이트에 접속하는지는 노출된다는 의미다. ISP, 네트워크 관리자, 국가 수준의 감시자가 사용자의 방문 사이트 목록을 수집할 수 있다.
이 문제를 해결하기 위해 ECH(Encrypted Client Hello)가 개발 중이다. ECH는 ClientHello 자체를 암호화하여 SNI를 포함한 모든 메타데이터를 숨긴다. Cloudflare와 Firefox가 ECH를 실험적으로 지원하고 있으며, 표준화가 진행 중이다.
HTTPS는 HTTP의 세 가지 근본 취약점(도청, 변조, 사칭)을 해결한다. 하지만 HTTPS가 만능이 아니라는 점을 이해하는 것이 중요하다.
| HTTPS가 보호하는 것 | HTTPS가 보호하지 않는 것 |
|---|---|
| 전송 중 데이터 암호화 | 서버 측의 데이터 저장 보안 |
| 전송 중 데이터 무결성 | 웹 애플리케이션 취약점 (XSS, SQLi) |
| 서버 도메인 인증 | 사이트 운영자의 신뢰성 |
| 쿠키·인증 토큰 보호 | 접속 사이트 메타데이터 (SNI) |
이 시리즈의 흐름을 정리하면 다음과 같다.
HTTPS의 가장 큰 약점은 첫 번째 연결이다. 사용자가 http://로 접속하면 공격자는 중간에서 HTTPS 업그레이드를 차단할 수 있다. HTTP Strict Transport Security(HSTS)는 이 문제를 해결한다. 서버가 Strict-Transport-Security 헤더를 보내면 브라우저는 이후 모든 요청을 자동으로 HTTPS로 전환한다. max-age가 31536000(1년)이면 그 기간 동안 HTTP 접속 자체가 불가능해진다.
하지만 HSTS도 최초 방문 시에는 무력하다. 이를 보완하는 것이 HSTS Preload 목록이다. Chrome, Firefox, Safari가 공유하는 이 목록에 등록된 도메인은 브라우저가 처음부터 HTTPS만 허용한다. 2025년 기준 약 25만 개 도메인이 등록되어 있다.
2011년 DigiNotar 사건은 인증서 시스템의 근본적 취약점을 드러냈다. 네덜란드 CA가 침해당해 google.com에 대한 허위 인증서가 발급됐고, 이란 사용자 30만 명의 Gmail 트래픽이 감청됐다. 이 사건 이후 구글은 Certificate Transparency(CT) 프로젝트를 시작했다.
CT는 모든 인증서 발급 내역을 공개 로그에 기록한다. 도메인 소유자는 자신의 도메인에 대해 발급된 모든 인증서를 모니터링할 수 있다. 2018년 4월부터 Chrome은 CT 로그에 기록되지 않은 인증서를 신뢰하지 않는다.
TLS 1.2에서 1.3으로의 전환은 단순한 버전 업그레이드가 아니다. RSA 키 교환이 제거되어 Forward Secrecy가 필수가 됐다. 이는 서버의 개인키가 유출되더라도 과거 통신 내용을 복호화할 수 없다는 의미다.
0-RTT(Zero Round Trip Time) 재연결 기능도 추가됐다. 이전에 연결한 서버에 다시 접속할 때 핸드셰이크 없이 즉시 데이터를 보낼 수 있다. 다만 이 기능은 재전송 공격(replay attack)에 취약할 수 있어, 비멱등(non-idempotent) 요청에는 사용하지 않는 것이 권장된다.
자물쇠 아이콘이 보장하는 것은 전송 구간의 암호화뿐이다. 서버가 수신한 데이터를 어떻게 저장하는지, 제3자에게 공유하는지는 HTTPS와 무관하다. Let's Encrypt의 무료 인증서 보급 이후 피싱 사이트의 83%가 유효한 HTTPS 인증서를 사용한다(PhishLabs, 2024). 자물쇠 아이콘만으로 사이트의 정당성을 판단하는 것은 위험하다.
HTTPS 페이지에서 HTTP 리소스를 로드하면 혼합 콘텐츠 문제가 발생한다. 이미지, 스크립트, 스타일시트가 HTTP로 로드되면 중간자 공격으로 변조될 수 있다. 특히 JavaScript가 HTTP로 로드되면 공격자가 스크립트를 교체하여 페이지 전체를 제어할 수 있다.
Chrome은 2020년부터 혼합 콘텐츠를 단계적으로 차단하기 시작했다. 능동적 혼합 콘텐츠(스크립트, iframe)는 즉시 차단되고, 수동적 혼합 콘텐츠(이미지, 오디오)는 경고와 함께 자동으로 HTTPS로 업그레이드를 시도한다. Content-Security-Policy: upgrade-insecure-requests 헤더를 사용하면 모든 HTTP 요청을 HTTPS로 자동 전환할 수 있다.
브라우저가 HTTPS 사이트에 접속하면 서버는 인증서 체인을 전송한다. 브라우저는 이 체인을 검증하기 위해 여러 단계를 거친다.
먼저 인증서의 유효 기간(Not Before, Not After)을 확인한다. 만료된 인증서는 즉시 거부된다. 다음으로 인증서의 도메인이 접속 URL과 일치하는지 확인한다. Subject Alternative Name(SAN) 필드에 나열된 도메인만 유효하다. 와일드카드 인증서(*.example.com)는 한 단계의 서브도메인만 커버한다.
체인 검증에서는 각 인증서가 상위 CA에 의해 올바르게 서명됐는지 확인한다. 최종적으로 루트 CA가 브라우저의 신뢰 저장소에 포함되어 있어야 한다. 이 과정에서 OCSP(Online Certificate Status Protocol) 또는 CRL(Certificate Revocation List)로 인증서의 폐기 여부도 확인한다.
Let's Encrypt의 등장은 HTTPS 보급의 전환점이었다. 2015년 출시 이후 무료 인증서 발급이 가능해지면서, 전체 웹 트래픽의 HTTPS 비율은 2015년 40%에서 2025년 95%로 급증했다.
HTTPS는 전송 계층의 암호화를 담당할 뿐, 애플리케이션 계층의 취약점이나 서버 측 보안 설정 미흡까지 보호하지는 않는다. 이 구분을 정확히 이해하는 것이 HTTPS 보안의 실체를 파악하는 첫 단계다.