7장 HTTPS
🍪 HTTP의 약점
- 평문 통신이기 때문에 도청이 가능하다.
- 통신 상대를 확인하지 않기 때문에 위장이 가능하다.
- 완전성을 증명할 수 없기 때문에 변조가 가능하다.
평문 통신의 약점인 도청
- HTTP는 자신을 암호화하는 기능이 없다.
- TCP/IP 구조의 통신 내용은 전부 통신 경로의 도중에 엿볼 수 있다.
- 네트워크 상을 흐르고 있는 패킷을 수집하는 것만으로 도청할 수 있다. (with 패킷 캡처, 스니퍼)
도청을 피할 수 있는 방법?
- 암호화를 한다.
- 통신 암호화 ⇒ SSL(Secure Socket Layer), TLS(Transport Layer Security) 프로토콜을 HTTP와 조합함으로써 통신 내용을 암호화. SSL 등을 이용해 안전한 통신로 확립. 이를 HTTPS(HTTP Secure)라고 한다.
- 콘텐츠 암호화 ⇒ 콘텐츠의 내용 자체를 암호화 (클라이언트와 서버가 콘텐츠 암호화 / 복호화 구조를 가지고 있는 것이 전제)
통신 상대를 확인하지 않아서 위장 가능
- request를 받은 서버가 URI에서 지정된 호스트인지, response를 반환받은 클라이언트가 진짜 request를 보낸 클라이언트인지 아닌지 알 수가 없다.
- 누구나 request를 할 수 있다.
이를 피할 수 있는 증명서
- SSL로 상대를 확인할 수 있다.
- SSL은 암호화뿐만 아니라 상대를 확인하는 수단으로 증명서를 제공한다.
- 증명서는 제3자 기관에서 발생되기 때문에 서버나 클라이언트가 실재하는 사실을 증명한다.
- 증명서를 위조하는 것은 기술적으로 상당히 어렵다.
- 클라이언트는 통신을 개시할 때 서버의 증명서를 확인한다. (통신 상대가 내가 통신하고자 하는 서버임을 나타냄)
완전성(정보의 정확성)을 증명할 수 없어 변조가 가능
- 수신한 내용이 다를 수도 있다. (변조되었다고 해도 이 사실을 알 수 없다.)
- 중간자 공격 (man in the middle) : 공격자가 도중에 request나 response를 빼앗아 변조하는 공격 (클라이언트와 서버는 정상적으로 통신하고 있는 것처럼 보여진다)
변조를 방지하려면?
- HTTP에도 방법이 있긴하다. 하지만 확실한 방법은 없다.
- MD5나 SHA-1 해시값을 확인하는 방법, 파일의 디지털 서명을 확인하는 방법
- 이조차 변조 될 수 있으므로 HTTP 만으로는 완전성을 보증하는 것이 어렵기 떄문에 다른 프로토콜을 조합해 실현한다.
🍪 HTTPS
HTTPS는 SSL이라는 껍질을 덮어쓴 HTTP
- HTTP 통신을 하는 소켓부분을 SSL이나 TLS라는 프로토콜로 대체
- 보통 HTTP는 직접 TCP와 통신하지만 SSL을 사용한 경우는 HTTP는 SSL과 통신하고 SSL이 TCP와 통신한다.
암호화 방식
- SSL은 공개키 암호화 방식을 채택
- 암호화, 복호화할 때 키를 사용한다. 키가 없으면 암호를 풀 수 없지만 반대로 키를 가진다면 아무나 암호를 풀 수 있다.
공통키 암호의 딜레마
- 공통키 암호 : 암호화와 복호화에 하나의 키를 같이 사용하는 방식
- 이는 상대방에게 키를 넘겨주지 않으면 안된다.
- 하지만 통신을 할 때 도청되어 공격자에게 키를 뺏기면 암호화의 의미가 없다.
- 애초에 키를 안전하게 보낼 수 있다면 틀림없이 데이터도 안전하게 보낼 수 있다.
두개의 키를 사용하는 공개키 암호
- 공개키 암호 : 서로 다른 두 개의 키 페어를 사용한다.
- 비밀키 : 누구에게도 알려지면 안되는 키
- 공개키 : 누구에게나 알려져도 괜찮은 키
- 공개키 암호화는 암호를 보내는 측이 공개키를 사용해서 암호화를 진행하고, 받은 상대가 비밀키를 이용해 복호화를 한다.
- 비밀키를 통신으로 보낼 필요가 없어 도청에 의해 키를 뺏길 걱정이 없다.
- 암호문과 공개키 정보에서 평문을 구하는 것이 매우 어렵다.
결국 HTTPS는 공통키 + 공개키 (하이브리드 암호 시스템)
- 공개키 암호는 공통키 암호에 비해 처리 속도가 늦다. (즉, 모든 통신에서 공개키 암호를 사용하는 것은 비효율적이다.)
- 두가지 장점을 살릴 수 있도록 각자의 방식을 조합해 통신한다.
- 키를 교환하는 곳에서는 공개키 암호를 사용하고, 그 이후의 통신에서는 공통키 암호를 사용한다.
공개키를 증명하기
- 문제 : 공개키가 진짜인지 아닌지 증명할 수 없음 (도중에 공격자가 공개키를 바꿔치기 했을 수 있다.)
- 해결 : CA(Certificate Authority, 인증 기관)과 인증 기관에서 발행하는 공개키 증명서가 이용된다.
- 인증 기관 : 클라이언트와 서버가 모두 신뢰하는 제 3자 기관 (예 | VeriSign)
인증 기관 이용 (CA)
- 서버의 운영자가 인증 기관에 공개키를 제출
- 인증 기관이 공개키에 디지털 서명을 함 ⇒ 디지털 서명된 공개키
- 공개키 인증서에 서명이 끝난 공개키를 담음 ⇒ 공개키 인증서(디지털 증명서, 증명서)
- 공개키 인증서를 클라이언트에 보내고 공개키 암호로 통신한다.
조직의 실제성 증명 (EV SSL)
클라이언트를 확인하는 클라이언트 증명서
- 서버가 통신하고 있는 상대가 의도한 클라이언트라는 것을 증명
- 문제 : 유저가 증명서를 직접 install 해야한다. 유료다. (유저수 만큼 비용)
- 이런 이유로 비용을 들일 필요가 있는 곳에서만 사용된다. (은행 인터넷 뱅킹)
- 하지만, 사용자 자체 존재 유무를 증명하진 않는다.
나야 나 증명서
- OpenSSL 등의 소프트웨어를 사용하면 누구든지 인증 기관을 구축할 수 있다.
- 독자적으로 구축한 인증 기관을 자기 인증 기관이라 불러, 거기서 발행한 쓸모 없는 증명서
HTTPS의 구조
- 클라이언트가 ClientHello 메시지를 송신하며 SSL 통신 시작
- 서버가 SSL 통신이 가능한 경우 ServerHello 메시지로 응답
- 서버가 Certificate 메시지를 송신한다. (with 공개키 증명서)
- 서버가 ServerHelloDone 메시지를 송신하여 SSL 네고시에이션이 끝남
- 클라이언트가 ClientKeyExchange 메시지로 응답하고 (with Pre-Master secret = 통신을 암호화하는데에 사용 = 공개키 증명서에서 꺼낸 공개키로 암호화 되어 있음)
- 클라이언트가 Change Cipher Spec 메시지를 송신 (= 이후 통신은 암호키를 사용해서 진행한다.)
- 클라이언트가 Finished 메시지를 송신 (with 접속 전체 체크값)
- 서버가 Change Cipher Spec 메시지를 송신
- 서버가 Finished 메시지를 송신
- 이제 SSL에 의한 접속이 확립된다. 이제부터 에플리케이션 계층의 프로토콜에 의해 통신 시작
(에플리케이션 계층의 데이터를 송신할 때는 MAC(Message Authentication Code)라고 부르는 메시지 다이제스트를 덧붙일 수 있다. = 이는 변조 감지)
SSL은 느리다?
- HTTP 통신에 비해 SSL 통신만큼 네트워크 리소스, CPU, 메모리를 소비한다. (HTTP에 비해 2배에서 100배 정도 느림)
- 서버와 클라이언트 모두 암호화와 복호화 처리가 필요하기 때문
- 근본적인 해결법은 없지만 SSL 엑셀레이터라는 하드웨어를 사용해서 문제를 해결한다. (빠른 계산)
8장 인증
인증이란?
- 본인인지 아닌지를 확인하기 위해서는 본인만이 아는 정보나 본인만이 가진 정보를 확인할 필요가 있다.
정보?
- 패스워트
- 원타입 토큰 : 본인이 가진 기기에만 보여지는 한번 쓰고 버리는 패스워드 등의 정보
- 전자 증명서 : 본인(단말기)만이 가지는 정보
- 바이오 매트릭스 : 지문이나 홍채 등
- IC 카드 등 : 본인만이 가지고 있는 정보
하지만 상대가 가짜여도 정보를 제시할 수 있다면 본인으로 인식해 버린다.
🍪 HTTP에서 사용하는 인증 방법
- BASIC 인증 ⇒ 잘 안쓴다.
- DIGEST 인증 ⇒ 잘 안쓴다.
- SSL 클라이언트 인증 ⇒ 비용 문제로 널리 쓰이진 않는다.
- 폼 베이스 인증 ⇒ 대부분 사용
BASIC
- HTTP/1.0에서 구현된 인증 방식
- 서버와 클라이언트 사이에서 이뤄지는 인증 방식
- Base64를 통해 인코딩하지만 암호화는 아니기 때문에 복호화 할 수 있다.
- 로그아웃이 불가능 하다.
- 보안 등급에 미치지 못해 그다지 사용되지 않음
- 서버에서 401 코드와 WWW-Authenticate 헤더 필드를 포함해 리스폰스를 반환
- WWW-Authenticate : 인증의 방식 (BASIC)과 보호 공간을 식별하기 위한 문자열 (realm) 포함
- 유저의 ID와 패스워드를 Base64 형식으로 인코딩해서 송신 (브라우저가 자동적으로 변환)
DIGEST
- BASIC 인증의 약점을 보안하며 HTTP/1.1에서 소개
- 첼린지 리스폰스 방식이 사용됨
- 서버가 첼린지 코드를 전송하고, 클라이언트에서 패스워드와 첼린지 코드를 이용해 리소폰스 코드를 계산한다. 이를 서버에게 보냄
- BASIC 인증에 비해 높은 보안 등급이지만, 도청 방지 보호기능은 제공하고, 위장 방지 기능을 제공하지 않기 때문에 취약하다.
- 보안 등급에 미치지 못해 그다지 사용되지 않음
- 서버가 인증이 필요하다고 401 코드를 보내면서, 첼린지 코드(nonce)를 송신
- nonce는 401 response를 반환할 때마다 생성되는 유일한 문자열
- 클라이언트가 첼린지 코드에서 리스폰스 코드를 계산해서 송신
SSL 클라이언트 인증
- ID와 패스워드를 이용해 인증 방식은 정보가 도난 되었을 때 취약하다.
- 이를 방지하기 위해 SSL 클라이언트 인증을 사용
- HTTPS의 클라이언트 인증서를 이용한 방식
- 사전에 등록된 클라이언트에서의 엑세스인지 아닌지를 확인할 수 있다.
- 비용이 필요하다.
- 서버는 클라이언트에게 클라언트 증명서를 요구하는 Certificate Request 메시지를 송신
- 유저는 송신할 클라이언트 증명서를 선택, 클라이언트는 선택된 증명서를 Client Certificate 메시지를 송신
- 서버는 클라이언트 증명서를 검증하고 결과가 정확하다면 클라이언트의 공개키를 취득
- 이후 HTTPS 통신
- SSL 클라이언트 인증은 단독으로 사용되지 않고 폼 베이스 인증 + 2-factor 인증의 하나로서 이용된다.
- 2-factor 인증 : 패스워드라는 단 하나의 요소만이 아닌 사용자가 가진 다른 정보를 병용해서 인증을 하는 방법
폼 베이스 인증
- HTTP 프로토콜로써 사양이 정의되어 있는 인증 방식은 아니다.
- 클라이언트가 서버에 자격 정보 (Credential)을 송신하여 자격 정보의 검증 결과에 따라 인증을 하는 방식
- 서버에 따라 인증의 방법이 다양하다.
- 대부분 ID, Password를 송신하고 검증 결과를 토대로 검증 성공 여부 결정
- 자격 정보를 교환하는 방법이 표준화되어 있지 않다. (서버에서 어떻게 저장해야될지도 표준화되어 있지 않음 ⇒ 일반적으로 salt라는 부가 정보를 사용해 저장한다. )
- HTTP가 표준으로 제공하는 BASIC이나 DIGEST 인증은 사용상, 보안적 문제로 거의 사용되지 않고 SSL 클라이언트 인증은 비용 문제로 널리 사용되지 않고 있다. 표준으로 제공되는 것들이 인증 기능으로써 요구되는 레벨을 충족시킨 것이 존재하지 않기 때문에 결국 제각각 구현하는 폼 베이스 인증을 채용할 수 밖에 없다.
쿠키
- 세션 관리를 위해 쿠키를 사용하는 방식이 있다.
- HTTP는 stateless 프로토콜로써 방금 인증을 성공했더라도 프로토콜 레벨에서 유지할 수가 없다. 즉, 상태 관리가 되지 않기 때문에 세션 관리와 쿠키를 통해 상태 관리 기능을 보충한다.
- 클라이언트가 자격 정보(ID, PW)를 전송한다.
- 서버측은 유저 식별을 위해 세션 ID를 발행하고, Set-Cookie 헤더 필드에 세션 ID를 저장해서 response를 반환
- 이는 도난당하거나 쉽게 유출돼서는 안된다. (유효기간 지장, 추측 어려운 문자열 사용, XSS 방지를 위해 쿠키에 httpOnly 속성 부여)
- 클라이언트는 서버로부터 받은 세션 ID를 쿠키에 저장하고 다음 request때는 브라우저가 자동으로 쿠키를 송출하기 때문에 세션 ID가 서버에 송신된다.
9장 HTTP에 기능을 추가한 프로토콜
- HTTP는 주로 HTML 문서를 전송하기 위해 만들어졌다.
- 시대가 지나면서 용도가 크게 변화하고 있다. (SNS, 쇼핑 사이트 등)
- 이로써 HTTP의 제한과 한계가 나타남
- 하지만 이미 브라우저 환경이 널리 퍼진 지금 HTTP라는 프로토콜을 무시할 수 없다.
- 그래서 HTTP를 기반으로 한 여러 새로운 프로토콜이 구현되었다.
🍪 HTTP의 병목 현상
- 페이스북과 트위터 같은 SNS는 데이터가 단시간에 대량의 갱신이 발생한다.
- 갱신된 정보를 빨리 실시간으로 표시하는 것에는 HTTP에 무리가 있다.
- 서버의 정보가 갱신되었는지 확인을 하기 위해서는 클라이언트가 항상 서버 측에 확인하러 가야한다.
- 이는 서버측 정보가 갱신되지 않았다면 불필요한 통신
어떤 병목 현상들이 있을까?
- 1개의 커넥션으로 1개의 리퀘스트만 보낼 수 있다.
- 리퀘스트는 클라이언트에서만 시작할 수 있다.
- 리퀘스트/리스폰스 헤더를 압축하지 않고 보낸다. (헤더의 정보가 많을수록 지연)
- 장황한 헤더를 보낸다. (매번 같은 헤더를 보내는 것은 낭비)
- 데이터 압축을 임의로 선택할 수 있다. (강제적이지 않다)
🍪 여러 해결들
- Ajax
- Comet
- SADY
- WebSocket
- HTTP/2.0
Ajax (Asynchronous JavaScript + XML)
- 웹 페이지의 일부분만 고쳐 쓸 수 있는 통신 방식
- js나 DOM 조작 등을 활용하는 방식
- 장점 : 페이지의 일부분만 갱신되기 때문에 response로 전송되는 데이터 양이 줄어든다. (일부 데이터만 받을 수 있다.)
- 단점 : 실시간으로 정보 취득을 위해서는 다량의 request가 발생한다. HTTP의 근본적인 문제가 해결되는 것은 아니다.
핵심 기술
- XMLHttpRequest라는 API로 JS등의 스크립트 언어로 서버와 HTTP 통신을 할 수 있다.
Comet
- 서버측의 데이터에 변경이 있을 때 request를 기다리지 않고 변경사항을 서버에서 송신
- 응답을 연장시킴으로써 서버 푸시 기능을 유사하게 따른다.
- 응답을 보류 상태로 해두고 콘텐츠가 갱신되었을 때 response 반환
- 단점 : response 보류를 위해 connection을 유지하는 시간이 길어진다. (커넥션 유지를 위한 리소스 소비). HTTP의 근복적인 문제가 해결되는 것은 아니다.
SADY (SPeeDY)
- 프로토콜
- HTTP의 근본적 개선을 위해 프로토콜 레벨의 개선
설계
- HTTP를 완전히 바꾸는 게 아니라 TCP/IP의 어플리케이션 계층과 트렌스포트 계층 사이에 새로운 세션 계층을 추가하는 형태 (세션 계층이 데이터 흐름 제어)
- 표준으로 SSL을 사용한다.
HTTP = 어플리케이션 계층
SPDY = 세션 계층 🥷
SSL = 프리젠테이션 계층
TCP = 트랜스포트 계층
SADY를 사용하면?
- 다중화 스트림 : 단일 TCP 접속을 통해 복수의 HTTP 리퀘스트를 무제한으로 처리
- 리퀘스트에 우선 순위 부여 : 물론 SPDY는 병렬처리가 가능하지만 대역폭 문제로 처리가 늦어지는 현상 해결위해
- HTTP 헤더 압축
- 서버 푸시 기능
- 서버 힌트 기능 : 서버가 클라이언트에게 리퀘스트 해야 할 리소스 제안 가능
SADY는 병목현상을 해결하는가?
- 웹 서버에 실험적으로 구현은 되어있지만 실제 웹 사이트 도입은 그다지 진행되지 않음
- SADY는 기본적으로 한개의 도메인과의 통신을 다중화하기 때문에 복수의 도메인으로 리소스를 사용하고 있으면 효과가 한정적이다.
WebSocket
- 프로토콜
- 웹 브라우저와 웹 서버를 위한 양방향 통신 규격
- Ajax나 Comet에서 사용하는 XMLHttpRequest의 결점을 해결하기 위한 기술
- WebSocket은 웹 서버와 클라이언트가 한번 접속을 확립하면 그 뒤의 통신을 모두 전용 프로토콜로 하는 방식
- HTTP에 의한 접속의 출발점이 클라이언트에 있다는 것은 변함이 없지만 한번 접속을 확립하면 서버와 클라이언트 어느 쪽에서도 송신을 할 수 있다.
특징
- 서버 푸시 기능
- 통신량의 삭감 : 접속을 유지하려 하기 때문에 접속 오버헤드가 적어진다. 통신을 위한 한번의 절차
- handshake
- HTTP의 Upgrage 헤더 필드를 사용해서 프로토콜을 변경하는 것으로 handshake 실시
🍪 HTTP/2.0
- 사용자가 웹을 이용할 때의 체감 속도의 개선을 목표로 함
사양 베이스
- SPDY
- HTTP Speed + Mobility
- Network-Friendly HTTP Upgrade
🍪 WebDAV (Web-based Distributed Authoring and Versioning)
- 분산 파일 시스템
- HTTP/1.1를 확장한 프로토콜
- 기능
- 파일 작성/삭제
- 관리/편집/잠금/갱신정보 관리