10장 : HTTPS와 네트워크 보안
암호화의 기초
HTTP는 데이터를 평문으로 전송합니다. 브라우저에서 서버로 보내는 비밀번호, 개인정보, 결제 정보가 네트워크를 지나는 동안 누구든 읽을 수 있다는 뜻입니다.
HTTP (평문)
Client ──"password=1234"──→ Server
↑
공격자: "password=1234 잘 보인다!"
HTTPS (암호화)
Client ──"x8f2k...a9z3"──→ Server
↑
공격자: "????" (읽을 수 없음)이 문제를 해결하는 것이 HTTPS이고, HTTPS의 핵심 기술이 TLS(Transport Layer Security)입니다. TLS를 이해하려면 먼저 암호화의 기본 개념을 잡아야 합니다.
대칭키 암호화
대칭키 암호화(Symmetric Encryption)는 암호화와 복호화에 같은 키를 사용하는 방식입니다.
암호화: 평문 + 키 → 암호문
"Hello" + KEY_ABC → "x8f2k"
복호화: 암호문 + 같은 키 → 평문
"x8f2k" + KEY_ABC → "Hello"
비유: 하나의 열쇠로 잠그고, 같은 열쇠로 연다| 알고리즘 | 키 길이 | 특징 | 상태 |
|---|---|---|---|
| AES-128 | 128비트 | 빠르고 안전 | 현재 표준 |
| AES-256 | 256비트 | 최고 보안 | 군사/금융용 |
| DES | 56비트 | 짧은 키 | 폐기됨 (깨짐) |
| 3DES | 168비트 | DES 3회 적용 | 사용 중단 권고 |
| ChaCha20 | 256비트 | 소프트웨어 최적화 | 모바일에서 인기 |
장점은 속도입니다. 비대칭키 방식에 비해 수백 배 빠르기 때문에, 대량의 데이터를 암호화하는 데 적합합니다.
Alice가 Bob에게 비밀 메시지를 보내려면:
1. Alice와 Bob이 같은 키를 공유해야 함
2. 키를 전달하려면... 안전한 채널이 필요
3. 안전한 채널이 있었으면 암호화가 필요 없었음!
Alice ──────?──────→ Bob
"키를 어떻게 보내지?"
(이 채널이 안전하지 않으니까 암호화가 필요한 건데...)
닭이 먼저냐 달걀이 먼저냐!
→ 이 문제를 해결하는 것이 비대칭키 암호화비대칭키 암호화
비대칭키 암호화(Asymmetric Encryption)는 두 개의 키를 사용합니다. 공개키(Public Key)와 개인키(Private Key)입니다.
키 쌍 생성
Bob이 공개키 + 개인키 쌍을 생성
공개키: 모두에게 공개 (전화번호부처럼)
개인키: Bob만 보관 (절대 유출 금지!)
암호화 (공개키로)
Alice가 Bob의 공개키로 암호화
"Hello" + Bob의 공개키 → "x8f2k"
복호화 (개인키로)
Bob만 자신의 개인키로 복호화 가능
"x8f2k" + Bob의 개인키 → "Hello"
핵심
공개키로 암호화 → 개인키로만 복호화
개인키로 암호화 → 공개키로만 복호화 (디지털 서명에 활용)| 알고리즘 | 키 길이 | 용도 | 특징 |
|---|---|---|---|
| RSA | 2048~4096비트 | 암호화, 서명 | 가장 널리 사용, 키가 큼 |
| ECDSA | 256비트 | 디지털 서명 | RSA 대비 작은 키로 동등 보안 |
| ECDH | 256비트 | 키 교환 | 타원곡선 기반 DH |
| Ed25519 | 256비트 | 서명 | 빠른 서명/검증, SSH 키로 인기 |
비대칭키: 느리지만 키 교환 문제 해결
대칭키: 빠르지만 키 교환 문제 있음
TLS의 해결책: 둘을 조합!
1. 비대칭키로 대칭키를 안전하게 교환
Alice ── Bob의 공개키로 대칭키 암호화 ──→ Bob
Bob: 개인키로 복호화 → 대칭키 획득
2. 이후 데이터는 대칭키(AES)로 암호화
Alice ← AES(대칭키) → Bob
속도 빠름!
결론
비대칭키 = "키 배달부" (느리지만 안전한 키 전달)
대칭키 = "실제 암호화" (빠른 데이터 암호화)해시 함수
해시 함수(Hash Function)는 임의 길이의 데이터를 고정 길이의 고유한 값(해시값)으로 변환하는 함수입니다.
1. 단방향성
"Hello" → a591a6d4... (가능)
a591a6d4... → "Hello" (불가능!)
2. 고정 길이
"Hi" → 32바이트 해시
"War and Peace" → 32바이트 해시 (같은 길이!)
3. 결정성
"Hello" → 항상 a591a6d4...
"Hello" → 항상 a591a6d4... (매번 동일)
4. 눈사태 효과
"Hello" → a591a6d40289...
"Hello!" → 7b0a22198c... (한 글자 차이, 완전히 다른 해시!)| 알고리즘 | 출력 길이 | 상태 | 용도 |
|---|---|---|---|
| MD5 | 128비트 | 취약 (충돌 발견) | 파일 체크섬만 |
| SHA-1 | 160비트 | 취약 (충돌 발견) | 사용 중단 |
| SHA-256 | 256비트 | 안전 | TLS, 비트코인 |
| SHA-384 | 384비트 | 안전 | 높은 보안 요구 |
| SHA-512 | 512비트 | 안전 | 높은 보안 요구 |
| BLAKE3 | 256비트 | 안전 | 차세대, 매우 빠름 |
import hashlib
import hmac
import secrets
# 해시 함수 데모
def hash_demo():
"""SHA-256 해시 계산"""
message = "Hello, TLS!"
hash_value = hashlib.sha256(message.encode()).hexdigest()
print(f"메시지: {message}")
print(f"SHA-256: {hash_value}")
print(f"길이: {len(hash_value)} hex chars = {len(hash_value)*4} bits")
# 눈사태 효과
message2 = "Hello, TLS?" # 느낌표 → 물음표
hash_value2 = hashlib.sha256(message2.encode()).hexdigest()
print(f"\n메시지: {message2}")
print(f"SHA-256: {hash_value2}")
print(f"1글자 차이인데 해시가 완전히 다름!")
# HMAC: 해시 + 비밀 키 = 메시지 인증 코드
def hmac_demo():
"""HMAC으로 메시지 무결성 + 인증 검증"""
key = secrets.token_bytes(32)
message = b"transfer: $1000 to account 1234"
mac = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f"\nHMAC: {mac}")
# 검증: 같은 키와 메시지면 같은 MAC
mac_verify = hmac.new(key, message, hashlib.sha256).hexdigest()
print(f"검증: {hmac.compare_digest(mac, mac_verify)}") # True
# 변조된 메시지
tampered = b"transfer: $9999 to account 5678"
mac_tampered = hmac.new(key, tampered, hashlib.sha256).hexdigest()
print(f"변조 검증: {hmac.compare_digest(mac, mac_tampered)}") # False
hash_demo()
hmac_demo()디지털 서명의 원리
디지털 서명(Digital Signature)은 비대칭키 암호화와 해시를 결합한 기술입니다.
서명 (송신자: Alice)
1. 문서의 해시값 계산: SHA-256("계약서 내용") → abc123...
2. 해시값을 Alice의 개인키로 암호화 → 서명값
3. [문서 + 서명값] 전송
┌───────────┐ 개인키 ┌──────────┐
│ 문서 해시 │──────────────→│ 서명값 │
│ abc123... │ 암호화 │ x9y8z7.. │
└───────────┘ └──────────┘
검증 (수신자: Bob)
1. 서명값을 Alice의 공개키로 복호화 → 해시값 A
2. 받은 문서의 해시값을 직접 계산 → 해시값 B
3. A == B이면 → ✓ 문서 변조 없음 + Alice가 서명함
┌──────────┐ 공개키 ┌───────────┐
│ 서명값 │───────────────→│ 해시값 A │
│ x9y8z7.. │ 복호화 │ abc123... │
└──────────┘ └───────────┘
↕ 비교
┌───────────┐ SHA-256 ┌───────────┐
│ 받은 문서 │──────────────→│ 해시값 B │
└───────────┘ │ abc123... │
└───────────┘
A == B → ✓ 유효한 서명!이 메커니즘은 TLS 인증서에서 핵심적으로 사용됩니다. CA가 인증서에 디지털 서명을 하고, 브라우저가 CA의 공개키로 서명을 검증하여 인증서의 진위를 확인합니다.
면접 포인트
| 질문 | 핵심 답변 |
|---|---|
| 대칭키 vs 비대칭키? | 대칭키는 같은 키, 빠름. 비대칭키는 두 키, 느리지만 키 교환 해결 |
| TLS에서 둘 다 쓰는 이유? | 비대칭키로 대칭키를 교환, 이후 대칭키로 데이터 암호화 (하이브리드) |
| 해시의 용도? | 무결성 검증 (데이터 변조 감지), 비밀번호 저장, 디지털 서명 |
| 디지털 서명 원리? | 해시값을 개인키로 암호화 = 서명, 공개키로 검증 |
다음 절에서는 이 암호화 기법들이 실제로 어떻게 조합되어 TLS 핸드셰이크를 이루는지 살펴보겠습니다.