HTTP/1.0
- 기본적으로 한 연결당 하나의 요청을 처리하도록 설계→ RTT (패킷 왕복 시간)증가

- 서버로부터 파일을 가져올 때마다 TCP의 3-웨이 핸드셰이크를 계속해서 열어야 함
▪️RTT의 증가를 해결하기 위한 방법
▫️이미지 스플리팅
많은 이미지를 다운로드받게 되면 과부하가 걸리기 때문에 많은 이미지가 합쳐 있는 하나의 이미지를 다운로드받고, 이를 기반으로 background-image의 position을 이용하여 이미지를 표기
1. 이미지 병합 예시 (수평으로 붙이는 경우)
[img1][img2][img3]...
만약 각 이미지가 100x100px 이고, 왼쪽에서부터 img1, img2, img3 순서로 배치되었다면:
2. CSS 예시
.sprite {
background-image: url('sprite.png');
width: 100px;
height: 100px;
display: inline-block;
}
.sprite.img1 { background-position: 0px 0px; }
.sprite.img2 { background-position: -100px 0px; }
.sprite.img3 { background-position: -200px 0px; }
▫️코드 압축
코드를 압축해서 개행 문자, 빈칸을 없애서 코드의 크기를 최소화
const express = require('express')
const app = express()
const port = 3000
app.get('/', (req, res) => {
res.send('Hello World!')
})
app.listen(port, () => {
console.log(`Example app listening on port ${port}`)
})
const express=require("express"),app=express(),port=3e3;app.get("/",(e,p)=>{p.send("Hello World!")}),app.listen(3e3,()=>{console.log("Example app listening on port 3000")});
▫️이미지 Base64 인코딩
이미지 파일을 64진법으로 이루어진 문자열로 인코딩
서버와의 연결을 열고 이미지에 대해 서버에 HTTP 요청을 할 필요가 없음
Base64 문자열로 변환할 경우 37% 정도 크기가 더 커지는 단점
▫️예시: Base64 이미지 사용
<img src="data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA..." />
또는 CSS에서:
.sprite {
background-image: url("data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAA...");
}
HTTP/1.1
- 매번 TCP 연결을 하는 것이 아니라 한 번 TCP 초기화를 한 이후에 keep-alive라는 옵션으로 여러 개의 파일을 송수신할 수 있게함
- HTTP/1.0에서도 keep-alive가 있었지만 표준화가 되어 있지 않았고 HTTP/1.1부터 표준화가 되어 기본 옵션으로 설정

- 한 번 TCP 3-웨이 핸드셰이크가 발생하면 그다음부터 발생하지 않음
- 문서 안에 포함된 다수의 리소스(이미지, css 파일, script 파일)를 처리하려면 요청할 리소스 개수에 비례해서 대기 시간이 길어지는 단점
▪️HOL Blocking
한 연결에서 앞선 요청이 처리되기 전까지 다음 요청이 대기해야 하는 현상

image.jpg가 느리게 받아진다면 그 뒤에 있는 것들이 대기하게 되며 다운로드가 지연되는 상태가 됨
▪️무거운 헤더 구조
HTTP/1.1의 헤더에는 쿠키 등 많은 메타데이터가 들어 있고 압축이 되지 않아 무거웠음
HTTP/2
- SPDY 프로토콜에서 파생된 HTTP/1.x보다 지연 시간을 줄이고 응답 시간을 더 빠르게 할 수 있음
- 멀티플렉싱, 헤더 압축, 서버 푸시, 요청의 우선순위 처리를 지원하는 프로토콜
▪️멀티플렉싱
- 하나의 TCP 연결 안에서 여러 개의 스트림(Stream)을 동시에 사용
- 특정 스트림의 패킷이 손실되었다고 하더라도 해당 스트림에만 영향을 미치고 나머지 스트림은 멀쩡하게 동작할 수 있다
스트림(stream) : 시간이 지남에 따라 사용할 수 있게 되는 일련의 데이터 요소를 가리키는 데이터 흐름


단일 연결을 사용하여 병렬로 여러 요청을 받을 수 있고 응답을 줄 수 있다
→ HTTP/1.x에서 발생하는 문제인 HOL Blocking을 해결
HTTP/1.1 (HOL Blocking)
[요청1] → [응답1]
↓
[요청2] (요청1 끝날 때까지 기다림
HTTP/2 (멀티플렉싱)
[요청1] →
[요청2] → 모두 동시에 전송됨
[요청3] →
응답도 순서와 상관없이 독립적으로 전달됨:
[응답2]
[응답1]
[응답3]
▪️헤더 압축

- HTTP/1.x에는 크기가 큰 헤더라는 문제→HTTP/2에서는 헤더 압축을 써서 해결
- 허프만 코딩 압축 알고리즘을 사용하는 HPACK 압축 형식
허프만 코딩
- 아직 테이블에 없는 새 헤더 값은 문자 자체를 압축해서 전송
- Huffman Coding이라는 압축 알고리즘 사용
✅ Huffman 압축 방식:
1. 각 문자의 등장 횟수 세기:
a: 5회
b: 2회
c: 1회
2. 등장 빈도에 따라 트리 생성
(빈도 낮은 것끼리 묶어서 트리 형태로 구성)
3. 문자별로 이진 코드(0,1) 할당:
a → 0 (자주 나오니까 코드 짧게)
b → 10
c → 11 (가장 드물게 나오니까 가장 긴 코드)
4. 문자열 aaaaabbc 압축 결과:
a a a a a b b c
0 0 0 0 0 10 10 11 → 총 11비트
→ 원래는 8 * 8 = 64비트
→ Huffman 압축 후 11비트
user-agent: Mozilla/5.0
→ "Mozilla/5.0" 자체를 Huffman 방식으로 압축해서 전송
▪️서버 푸시
HTTP/1.1에서는 클라이언트가 서버에 요청을 해야 파일을 다운로드받을 수 있었다면, HTTP/2는 클라이언트 요청 없이 서버가 바로 리소스를 푸시할 수 있다.

html에는 css나 js 파일이 포함되기 마련인데 html을 읽으면서 그 안에 들어 있던 css 파일을 서버에서 푸시하여 클라이언트에 먼저 줄 수 있다
HTTPS
HTTPS = HTTP + TLS
HTTPS는 HTTP 위에 TLS 보안 계층을 입힌 형태 HTTP는 원래 암호화되지 않은 프로토콜이지만, TLS를 통해 암호화할 수 있다
클라이언트 ←→ [ TLS ] ←→ 서버
[ HTTP ]
애플리케이션 계층과 전송 계층 사이에 신뢰 계층인 SSL/TLS 계층을 넣은 신뢰할 수 있는 HTTP 요청
▪️SSL/TLS
|
용어
|
설명
|
|
SSL (Secure Sockets Layer)
|
오래된 버전 (1990년대 개발)
|
|
TLS (Transport Layer Security)
|
SSL의 후속 버전. 지금은 거의 TLS만 사용합니다. 최신은 TLS 1.3
|
👉 일반적으로는 “SSL”이라 부르지만, 실제로는 대부분 “TLS”를 사용
- 전송 계층에서 보안을 제공하는 프로토콜
- 클라이언트와 서버가 통신할 때 SSL/TLS를 통해 제3자가 메시지를 도청하거나 변조하지 못하도록 함
- 인터셉터(공격자가 서버인 척하며 사용자 정보를 가로채는 것)를 방지
- 보안 세션을 기반으로 데이터를 암호화하며 보안 세션이 만들어질 때 인증 메커니즘, 키 교환 암호화 알고리즘, 해싱 알고리즘이 사용
보안 세션
- 보안이 시작되고 끝나는 동안 유지되는 세션
- 핸드셰이크를 통해 보안 세션을 생성하고 이를 기반으로 상태 정보 등을 공유
세션 : 운영체제가 어떠한 사용자로부터 자신의 자산 이용을 허락하는 일정한 기간을 뜻한다. 즉, 사용자는 일정 시간 동안 응용 프로그램, 자원 등을 사용할 수 있다.

클라이언트에서 사이퍼 슈트(cypher suites)를 서버에 전달하면 서버는 받은 사이퍼 슈트의 암호화 알고리즘 리스트를 제공할 수 있는지 확인합니다. 제공할 수 있다면 서버에서 클라이언트로 인증서를 보내는 인증 메커니즘이 시작되고 이후 해싱 알고리즘 등으로 암호화된 데이터의 송수신이 시작됨
사이퍼 슈트
프로토콜, AEAD 사이퍼 모드, 해싱 알고리즘이 나열된 규약
- TLS_AES_128_GCM_SHA256
- TLS_AES_256_GCM_SHA384
- TLS_CHACHA20_POLY1305_SHA256
- TLS_AES_128_CCM_SHA256
- TLS_AES_128_CCM_8_SHA256
예를 들어 TLS_AES_128_GCM_SHA256에는 세 가지 규약이 들어 있는데 TLS는 프로토콜, AES_128_GCM은 AEAD 사이퍼 모드, SHA256은 해싱 알고리즘을 뜻함
AEAD 사이퍼 모드
데이터 암호화 알고리즘이며 AES_128_GCM 등이 있음
예: AES_128_GCM
- AES: 표준 블록 암호화 알고리즘
- 128: 128비트 키 사용
- GCM: Galois/Counter Mode — 병렬 처리 가능 + 인증 기능 포함
인증 메커니즘
CA(Certificate Authorities)에서 발급한 인증서를 기반으로 이루어짐
CA (Certificate Authority)
웹 서버가 진짜인지 확인하는 “신뢰기관”
- 공개키 기반 인증서를 발급
- 브라우저는 이 CA를 신뢰 목록에 저장하고 있음
CA 인증서 발급 과정
- 서버가 CA에 다음을 제출:
- CA는 공개키에 대해 디지털 서명:
- 발급된 인증서를 서버가 설치 → 사용자는 이 인증서를 받아 신뢰 여부 확인
|
용어
|
설명
|
|
공개키 (Public Key)
|
누구나 볼 수 있음. 데이터를 암호화할 때 사용
|
|
개인키 (Private Key)
|
오직 본인만 소유. 복호화나 서명할 때 사용
|
|
둘은 수학적으로 연결되어 있지만, 개인키는 유추할 수 없음
|
|
키 교환 알고리즘
서로 **공통된 대칭 키(세션 키)**를 안전하게 만드는 방법
주요 방식:
- ECDHE: 타원 곡선 기반 → 빠르고 안전
- DHE: 전통적인 디피-헬만 방식
둘 다 **일회용 키(Ephemeral)**를 사용 → Perfect Forward Secrecy 보장
디피-헬만(Diffie-Hellman) 키 교환 원리
수학적으로는 이산 로그 문제의 어려움을 이용
원리 (단순화 버전):
- 공통된 숫자: g, p (공개)
- 클라이언트 비밀: a
- 서버 비밀: b
양쪽에서:
A = g^a mod p (클라이언트가 계산)
B = g^b mod p (서버가 계산)
공유 키 = B^a mod p = A^b mod p
핵심:
- 누군가 g, p, A, B를 안다고 해도 a나 b를 거의 알 수 없음
- → 안전하게 같은 대칭키를 공유할 수 있음
해싱 알고리즘
입력 데이터를 고정된 길이의 난수 같은 값으로 바꾸는 함수
특징
- 입력 데이터가 아무리 커도 출력은 항상 고정된 길이
- 복원 불가능: 해시값만으로 원래 데이터를 알아낼 수 없음
- 변화에 민감: 입력 데이터가 1비트만 달라도 완전히 다른 결과
SHA-256
SHA (Secure Hash Algorithm) 계열 중 하나**출력값이 항상 256비트(=32바이트)**인 해시 함수
SHA-256 작동 원리 (간단한 흐름)
- 입력 메시지 준비
- 전처리 (Padding)
- 초기 해시 값 설정 (8개의 상수)
- 블록별 처리 (압축함수)
- 최종 해시 결과 출력 (256비트)
SHA-256 예시
입력: "hello"
출력: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
↑ 총 64자리 (16진수) = 256비트
HTTP/3
TCP 위에서 돌아가는 HTTP/2와는 달리 HTTP/3은 QUIC이라는 계층 위에서 돌아가며, TCP 기반이 아닌 UDP 기반으로 돌아감
HTTP/2에서 장점이었던 멀티플렉싱을 가지고 있으며 초기 연결 설정 시 지연 시간 감소라는 장점이 있음
▪️초기 연결 설정 시 지연 시간 감소
QUIC은 TCP를 사용하지 않기 때문에 통신을 시작할 때 번거로운 3-웨이 핸드셰이크 과정을 거치지 않아도 됨

- QUIC은 첫 연결 설정에 1-RTT만 소요
- 순방향 오류 수정 메커니즘(FEC, Forword Error Correction) 적용
'CS > Network' 카테고리의 다른 글
| IP 주소 (0) | 2025.07.04 |
|---|---|
| TCP/IP 4계층 모델 (0) | 2025.07.04 |
| 네트워크의 기초 (0) | 2025.07.03 |