🤔 "왜 모든 사이트가 HTTPS를 사용해야 할까?"
🤔 "정말 100% 안전한 걸까?"
HTTPS는 HTTP의 보안 강화 버전입니다. 마치 일반 우편과 등기우편의 차이처럼, 같은 목적이지만 보안 수준이 다릅니다.
HTTP는 웹브라우저와 서버가 TCP를 통해 직접 대화합니다. 반면 HTTPS는 중간에 SSL/TLS라는 보안 계층이 끼어듭니다.
HTTP: 브라우저 ↔ TCP ↔ 서버
HTTPS: 브라우저 ↔ SSL/TLS ↔ TCP ↔ 서버
이 SSL/TLS가 바로 데이터를 암호화해주는 핵심 기술입니다.
1단계: TLS Handshake - 서버 신원 확인 및 키 교환
1. Client Hello
클라이언트 → 서버: "지원하는 암호화 방식 목록이야"
2. Server Hello + Certificate + Key Exchange
서버 → 클라이언트: "이 방식 쓸게 + CA에서 발급받은 내 인증서야 + 내 임시 공개키야"
3. 인증서 검증
클라이언트: 브라우저에 내장된 CA 목록으로 인증서 검증
→ "이 서버가 진짜 네이버/구글이 맞나?" 확인
4. Client Key Exchange + Key Derivation
클라이언트: 자신의 임시 키쌍 생성 → 공개키를 서버에 전송
양측: ECDHE/DHE 알고리즘으로 공유 비밀 계산
→ 이 공유 비밀에서 세션키(대칭키) 도출
5. Finished Messages
양측: 새로 만든 세션키로 "handshake 완료" 메시지 암호화하여 전송
→ 키 교환이 성공적으로 완료되었는지 확인
핵심 개선점: 현대 TLS에서는 Perfect Forward Secrecy를 제공합니다. 서버의 개인키가 유출되어도 과거 세션의 데이터는 안전하게 보호됩니다.
2단계: 실제 데이터 전송 (대칭키 암호화)
클라이언트 ⇄ 서버:
공유된 세션키로 모든 데이터 암복호화하여 빠르게 소통
예전에는 "HTTPS가 느리다"는 인식이 있었습니다. 암호화/복호화 과정에서 리소스를 더 많이 사용하거든요. 하지만 지금은 오히려 HTTPS가 더 빠른 경우가 많습니다.
HTTPS가 더 빠른 이유:
HTTPS는 데이터가 이동하는 동안만 암호화합니다. 서버에 도착한 후에는 일반 텍스트로 저장될 수 있습니다. 마치 택배가 배송 중에만 포장되어 있고, 도착하면 포장을 뜯는 것과 같습니다.
서버가 해킹당하면 저장된 데이터는 여전히 위험합니다. 이런 문제를 해결하려면 데이터베이스 암호화, 애플리케이션 레벨 암호화, 필드별 암호화 등의 추가 보안 조치가 필요합니다.
참고: 종단간 암호화(E2EE)는 메시징 앱처럼 서버가 메시지 내용을 알 필요가 없는 특수한 경우에 주로 사용됩니다. 일반 웹 서비스에서는 서버가 데이터를 처리해야 하므로 E2EE 적용이 제한적입니다.
간혹 신뢰할 수 없는 CA가 문제를 일으키는 경우가 있습니다.
실제 사례: DigiNotar 사건(2011) - 네덜란드 CA인 DigiNotar가 해킹당해 공격자들이 CA의 정당한 권한을 악용하여 구글, 야후 등의 무단 인증서를 발급했습니다. 기술적으로는 유효한 인증서였기 때문에 브라우저가 신뢰했고, 이를 통해 중간자 공격이 성공했습니다.
예를 들어, 서로 다른 이메일 서비스(Gmail, Naver 메일 등)를 사용하는 사용자들 간에 이메일을 주고받을 때, 두 서비스 간에 항상 동등한 수준의 암호화가 이루어진다고 보장할 수 없습니다.
중간자 공격은 공격자가 클라이언트와 서버 사이에 끼어들어 통신을 가로채는 공격입니다.
공격 시나리오:
1. 공격자가 가짜 Wi-Fi 핫스팟을 만들거나 네트워크를 장악
2. 사용자가 웹사이트에 접속할 때 공격자의 가짜 인증서를 제시
3. 사용자 브라우저가 경고를 무시하고 연결하면 공격자가 모든 통신 내용을 볼 수 있음
방어책:
완벽하지 않더라도 아무것도 하지 않는 것보다는 훨씬 낫습니다. 마치 집에 문을 잠그는 것처럼, 기본적인 보안 조치는 반드시 필요합니다.
Service Worker, Web Push, WebRTC 등 최신 웹 기능들은 대부분 보안 컨텍스트에서만 동작합니다.
브라우저가 "안전한 컨텍스트(HTTPS)에서는 안전하지 않은 리소스(HTTP) 사용 금지" 정책을 적용하고 있습니다.
HSTS, CSP(Content Security Policy)등 고급 보안 기능들을 활용할 수 있게 해줍니다.
HSTS(HTTP Strict Transport Security)는 브라우저가 특정 사이트에 HTTPS로만 접속하도록 강제하는 보안 메커니즘입니다. 사용자가 실수로 HTTP로 접속하려고 해도 자동으로 HTTPS로 변경해줍니다.
1. Strict-Transport-Security 헤더 사용
httpStrict-Transport-Security: max-age=31536000; includeSubDomains; preload
사용자가 HTTPS로 첫 방문할 때 서버가 브라우저에게 "앞으로 이 사이트는 HTTPS만 사용하라"고 명령하여, 이후 HTTP 접속 시도 시 브라우저가 자동으로 HTTPS로 변경합니다.
2. HSTS Preload
웹사이트를 미리 등록하여 브라우저 업데이트 시 해당 도메인 목록이 브라우저에 내장되므로, 사용자가 첫 방문부터 자동으로 HTTPS로 접속하게 됩니다.
HTTPS에 대해서 정리하면서 마치 현관문과 같다고 느꼈습니다. 완벽하지는 않지만, 웹 보안상 중요합니다.
그리고 추가적인 보안을 위해, 걸쇠를 걸거나 보안업체를 사용하듯 HTTPS의 한계를 보완하기 위해서 HTTPS에 더해 추가적인 보안 조치(ex: 웹 보안 헤더, 2차 인증, 데이터 보호 등)들을 함께 적용해야 합니다.
개발자로서 우리가 할 수 있는 일은 HTTPS를 기본으로 적용하고, 사용자 데이터를 한 번 더 보호할 수 있는 방법들을 지속적으로 고민하는 것이라고 생각합니다.