📕 목차
1. HTTP
2. HTTPS
1. HTTP
📌 HTTP(Hyper Text Transfer Protocol) 1.0
- WWW(World-Wide-Web) 상에서 Client와 Server 간에 요청과 응답으로 정보를 주고받을 수 있는 프로토콜
- 하이퍼 텍스트(HyperText)
- Web 상에 존재하는 Web Page끼리 서로 참조할 수 있는 기술
- Web에서 HyperText는 마크업 언어인 HTML로 표현된다.
- TCP, UDP를 사용하며 80번을 기본 port로 사용한다. (Well-known port)
- 비연결(Connectionless)
- Client가 Server에 요청을 보내고 Server가 적절한 응답을 돌려주면 연결이 바로 끊긴다.
- 간단하고 구현이 용이하다.
- 동일한 Client의 모든 요청에 매번 새로운 socket을 연결 및 해제 과정을 거치는 overhead 발생
- 무상태(Stateless)
- 연결을 끊는 순간 Client와 Server간의 통신이 끊긴다.
- Server는 연결이 끊긴 Client의 상태 정보를 유지하지 않는다.
- Server는 Client를 식별할 수 없으므로, 매번 인증 과정을 수반해야 한다.
- 단방향
- 언제나 Client가 먼저 요청을 보내고, Server는 요청에 대한 응답을 전송한다.
⚠️ HTTP 1.0의 문제점
- HTTP가 도입될 때만 해도 인터넷은 소수의 공돌이들이 점유하던 곳이었고, 그만큼 순수(?)한 사람들이 모여있던 공간이다보니 보안성이 떨어진다.
- 암호화되지 않은 평문 통신이기 때문에 도청이 가능하다.
- 통신 상대를 확인하지 않기 때문에 위조 요청이 가능하다.
- 데이터 무결성(완정성)을 증명할 수 없으므로 데이터를 변조할 수 있다.
- 매번 새롭게 socket을 다시 연결하는 과정에서 서버 부하 증가
📌 HTTP 1.1
- Persistent Connection
- 지정한 시간 동안 Connection을 닫지 않는다.
- 한 번 연결된 TCP socket은 keep-alive 옵션으로 일정 시간 동안 연결 상태를 유지하도록 한다.
- 동일한 Client에 대해 네트워크 사용시간 감소
- Pipelining
- TCP 특성인 요청 후 대기 시간을 무시하고, 가능한 전송 최대치를 연속적으로 보낸다.
- Server는 헤더를 기반으로 요청의 순서를 재조립하여 Application 계층으로 전달한다.
- Response Time 감소
파이프라인에 대한 설명은 예전에 정리했었다.
⚠️ HTTP 1.1의 문제점
- HOL(Head Of Line Blocking) Blocking
- 패킷에 따른 Server의 처리 시간의 차이로 인해 발생
- 1, 2, 3번 요청에 대해 2, 3번이 아무리 빨리 끝나도 1번이 늦어지면, 모든 요청은 blocking된다.
- pipeline에서 Server는 반드시 요청 순서에 맞춰 응답해야 하기 때문
- Header 구조의 중복
- 연속된 요청은 보통 payload 외에 header의 대부분 필드가 비슷함에도 불구하고, 중복을 따로 처리하지 않는다.
- 주고 받는 데이터 크기가 쓸 데 없이 크다.
📌 HTTP2
- HTTP/1.X 버전의 성능 향상(대체가 아닌 확장)에 초점을 맞춘 프로토콜
- Google에서 출시했으며, 처음에는 SPDY 프로토콜을 따라 모델링되었다.
- 페이지 로드 대기 시간을 최소화하기 위한 목적
- 멀티플렉싱, 헤더 압축 및 스트림 우선순위 지정과 같은 개념을 도입했다.
- Multiplexed Streams
- HTTP/1.1은 한 번의 연결에 여러 요청을 보내는 Pipeline은 지원했지만, 동시에 여러 요청을 처리하지는 못 하는 한계 존재
- 하나의 Connection 내의 여러 Stream(양방향 흐름)을 사용하여 송수신
- 메시지가 이진화된 텍스트인 Frame으로 나뉘어 요청마다 구분되는 Stream을 통해 전달
- Frame이 각 요청의 Stream을 통해 전달되며, 하나의 Connection 내에 여러 개의 Stream을 가질 수 있게 되어 다중화(Multiplexing) 가능
- Stream을 통해 각 요청의 응답 순서에 의미가 없어져서 HOL Blocking 이슈 해결
- Header Compression
- Bynary Framing 계층 추가
- 요청과 응답 헤더의 metadata를 Encoding하여, 중복 헤더로 인한 overhead 해결
- 이전에 표시된 헤더를 제외한 필드를 허프만 코딩으로 압축 (중복되지 않은 헤더만 추출해서 압축)
- 파싱을 통해 전송 속도 증가와 오류 발생 가능성 감소
- Server Push
- Client가 Server에 요청하지 않아도, Client에 필요한 Resource를 Server가 추가적으로 push 한다.
- 예를 들어, Client가 A라는 자원을 요청했는데 Server가 "어차피 B, C도 필요하겠네?"싶으면 Client가 요청하기 전에 같이 보내버린다. (push promise)
- Stream Prioritization
- Resource간 우선 순위 설정 가능
- Stream의 가중치를 조절하여, 먼저 전달할 data을 지정할 수 있다.
⚠️ HTTP2의 문제점
- 여전히 TCP 고유의 HOL Blocking이 존재
- 서로 다른 stream에서, 하나의 stream에 유실이 발생되거나 문제가 생기면 결국 다른 stream도 문제가 해결될 때까지 지연된다.
- 느린 Network에서 작동하는 Client system의 경우 데이터 패킷이 조금씩 떨어지고, 단일 HTTP/2 연결로 네트워크 품질 저하
- 이로 인해 전체 프로세스 속도 감소와 많은 데이터 전송이 차단
- 쿠키 보안 오류
- 쿠키는 서버와 웹사이트에서 얻은 클라이언트 데이터가 포함된 .txt 파일
- 이러한 쿠키는 비밀번호 없이도 개인 사용자 데이터에 접근할 수 있는 해커에 의해 도난당하거나 변조될 수 있다.
📌 HTTP3
- TCP 계층이 아닌 QUIC 계층 위에서 동작
- 전송 계층 프로토콜
- UDP 계층 기반 (TCP는 신뢰성을 확보하지만 지연을 줄이기 힘든 구조)
- 데이터 전송에 집중한 설계 (TCP만큼 신뢰성 확보가 가능한 UDP 기반 프로토콜)
- 이미 정해진 헤더가 많은 TCP 대신, 자유분방한 UDP를 건드리기가 더 쉬웠기 때문
- 패킷 손실 효과 감소, 왕복 시간 0, 보다 포괄적인 암호화, 보다 빠른 연결 설정같은 솔루션 제공
- HTTP/2.0의 장점과 기능을 갖는다
- 초기 연결 설정 시 지연 시간 감소
- TCP의 3-way handshaking 과정이 없어지므로 1-RTT로 초기 연결 가능
- 첫 연결 설정에서 필요한 정보와 함께 데이터를 전송한다.
- 연결 성공 시, 설정을 캐싱하여 다음 연결 때 바로 성립 가능
- Connection UUID라는 고유 식별자로 Server와 연결하기 때문에 Connection 재수립이 필요없다. (이동하면서 ip 주소가 바뀌어도 UUID로 식별하므로 재수립 단계 불필요)
- TCP의 Stream처럼 하나의 Chain으로 연결되는 것과 달리, 각 Stream 당 독립된 Stream chain을 구성하여 TCP 고유의 HOL Blocking 해결
- TLS를 기본 적용하여 IP Spoofing, Replay Attack 방지
2. HTTPS
📌 HTTPS(HTTP Secure)
- 4계층 SSL(Secure Sockets Layer) 프로토콜 위에서 동작하는 7계층의 HTTP 프로토콜
- 기존 HTTP 통신과 달리, 제 3자인 신뢰할 수 있는 기관으로부터 Server 또는 Client에 SSL 인증서를 발급하여 보증하는 방법
- 데이터 암호화, 인증, 무결성(완전성) 보호가 더해진 프로토콜
- 기본 포트로 443 port 사용
- socket 통신에서 일반 텍스트가 아닌, Web 상에서 정보를 암호화하는 SSL이나 TLS(Transport Layer Security) 프로토콜을 통해 세션 데이터 암호화
- SSL, TLS 모두 주요 목표는 기밀성, 데이터 무결성, ID 및 디지털 인증서를 사용한 인증을 제공하는 것
- HTTPS 특징
- Network 상에서 열람 및 수정 불가능하도록 데이터를 암호화한다.
- 암호화 과정이 웹 서버에 부하, 설치 및 인증서를 유지하는 데 추가 비용 → 느리다.
- socket 자체 인증 과정이 있어서, Connection이 끊기면 재인증하는 시간 소요
🤔 HTTPS가 HTTP보다 느리다며?
- 이론 상, HTTPS는 HTTP보다 느려야 하지만 실제로는 300%이상 더 빠르게 로딩된다고 한다.
- 그 이유는 구글이 개발한 SPDY를 지원하는 브라우저를 사용할 때 해당된다.
- 크롬10 이상, 파이어폭스13 이상, 오페라 12.10 이상, 안드로이드 브라우저 3.0 이상, 사파리8 이상 등
- SPDY를 지원하지 않는 네이티브 환경에서는 해당 프로토콜이 자동으로 적용되지 않으므로, 실제 테스트를 수행해봐야 실제 수행 속도 차이를 알 수 있을 것이다.
- 그리고 더 찾아봤는데, 오늘날에는 워낙 대역폭(HW쪽 기술 발달)이 넓어져서 거의 차이를 느낄 수 없는 정도라고 한다.
🟡 대략적인 HTTPS 통신 과정
- Client가 Server로 최초 연결 시도
- Server가 Public Key(인증서, 비대칭키)를 Client에게 전송
- Client는 인증서 유효성을 검사하고 세션키(대칭키) 발급
- Client는 세션키를 보관하며, 추가로 Server측의 public key로 세션키를 암호화하여 Server로 전송
- Server는 Private Key(개인키)로 암호화된 세션키를 복호화하여 세션키 획득
- Client와 Server가 동일한 세션키를 공유하므로 데이터 전달 시 세션키로 암복호화 진행
오늘 날엔 위처럼 대칭키 암호화, 비대칭키 암호화를 같이 사용한다. (하이브리드 방식)
📌 대칭키 암호화(Symmetric Key Cryptosystem)
- 대칭키(공용키) 암호화 전략
- Client와 Server가 동일한 키를 사용해 암복호화 진행
- Key가 노출되면 매우 위험하지만, 단순해서 연산 속도 빠름
- 암호화 종류
- DES (Data Encryption Standard; 데이터 암호화 표준)
- 3DES (Triple DES; 3중 데이터 암호화 표준)
- AES (Advances Encryption Standard; 고급 암호화 표준)
📌 비대칭키 암호화(Asymmetric Key Cryptosystem)
- 비대칭키(공개키, 개인키) 암호화
- 공개키 암호화: 개인키로만 복호화 가능하며, 개인키를 소유한 Server만 확인할 수 있다.
- 개인키 암호화: 공개키로만 복호화 가능하며, 누구나 확인 가능하면서 Server가 인증한 정보임을 알려 신뢰성을 보장할 수 있다.
- 1개의 쌍으로 구성된 공개키와 개인키로 암복호화 하는데 사용
- 공개키는 모두에게 공개 가능하며, 비밀키는 노출되어선 안 되므로 한 쪽에서만 관리한다.
- 한 쪽의 키만 가지고 다른 키를 만들거나, 암호화된 데이터를 해독할 수 없다.
- 키가 노출되어도 비교적 안전하지만 연산 속도 느림
- 암호화 종류
- RSA (Rivet Sharmir Adleman)
- 타원 곡선 암호 (Elliptic Curve Cryptosystem)
📌 SSL 동작 과정 (feat. Hybrid 방식)
기존의 하이브리드 방식은 Server가 Client에게 바로 공개키를 제공했지만,
CA라는 제 3자의 개입을 통해 높은 보안성을 보장한다.
📌 SSL Handshake
- 인증서 설치가 모두 끝난 후, SSL은 바로 데이터를 암호화하여 전달하지 않고 SSL Handshake 과정을 거쳐 세션(Session)을 맺는다.
- Phase 1: 양 측이 사용할 알고리즘 결정
- Phase 2: Client와 Server 간에 인증
- Phase 3: 공통키 교환
- Phase 4: 최종 확인