안동민 개발노트 아이콘

안동민 개발노트

10장 : HTTPS와 네트워크 보안

암호화의 기초

HTTP는 메시지를 평문으로 보냅니다. 같은 네트워크의 관찰자는 요청 경로, 쿠키, 본문에 담긴 민감 정보를 볼 수 있고, 중간자가 응답을 바꿔치기할 수도 있습니다. HTTPS는 이 문제를 줄이기 위해 HTTP를 TLS(Transport Layer Security) 위에 올립니다.

TLS를 이해하려면 “암호화”를 하나의 기능으로 뭉뚱그리면 안 됩니다. 실제 보안 연결은 대칭키 암호, 공개키 기반 인증과 키 교환, 해시, MAC, 디지털 서명을 서로 다른 역할로 조합합니다.


대칭키 암호화

대칭키 암호화(Symmetric Encryption)는 암호화와 복호화에 같은 비밀 키를 사용하는 방식입니다. 속도가 빠르기 때문에 TLS에서 실제 애플리케이션 데이터를 보호하는 데 쓰입니다.

대칭키 암호화 동작
암호화:  평문 + 비밀 키 + nonce  → 암호문
복호화:  암호문 + 같은 키 + nonce → 평문

핵심: 양쪽이 같은 비밀 키를 이미 알고 있어야 한다
알고리즘/방식키 길이 예시현재 실무 판단
AES-GCM128/256비트TLS에서 널리 쓰이는 AEAD 방식
ChaCha20-Poly1305256비트소프트웨어 구현에서 성능이 좋은 AEAD
AES-CBC + HMAC128/256비트과거 TLS 1.2에서 사용, 구성 주의 필요
DES56비트안전하지 않아 사용하면 안 됨
3DES112비트 수준레거시 호환 외에는 사용 중단 방향

대칭키 암호의 핵심 문제는 “키를 어떻게 안전하게 공유할 것인가”입니다. 네트워크에 비밀 키를 그대로 보내면 중간자가 그 키를 보고 이후 통신을 모두 읽을 수 있습니다. 그래서 TLS는 핸드셰이크에서 키 교환을 먼저 수행하고, 그 결과로 만들어진 트래픽 키를 대칭키 암호에 사용합니다.


공개키 암호와 키 교환

공개키 암호 방식은 공개키와 개인키라는 서로 다른 키를 사용합니다. 공개키는 배포할 수 있지만, 개인키는 소유자만 보관해야 합니다. 다만 현대 TLS에서 공개키 기술의 핵심 용도는 “대량 데이터를 공개키로 암호화”하는 것이 아니라 서버 인증, 서명, 키 교환입니다.

기술주된 역할설명
RSA-PSS디지털 서명인증서 체인이나 핸드셰이크 서명에 사용
ECDSA디지털 서명작은 키로 효율적인 서명/검증
Ed25519디지털 서명SSH 등에서 널리 쓰이며 TLS에서도 지원 가능
ECDHE임시 키 교환전방 비밀성을 제공하는 TLS 핵심 방식
RSA key transport레거시 키 운반 방식TLS 1.3에서는 제거, TLS 1.2에서도 비권장

공개키 암호를 이해할 때 가장 흔한 오해는 “공개키로 세션 키를 암호화해서 보내면 TLS가 끝난다”는 설명입니다. 과거 TLS 1.2에는 RSA key transport가 있었지만, 현대 TLS는 ECDHE 같은 임시 키 교환으로 공유 비밀을 만들고, 인증서는 그 키 교환이 진짜 서버와 이루어졌는지 확인하는 데 사용합니다.


TLS의 하이브리드 구조

TLS는 하나의 암호 기법만 쓰지 않습니다. 핸드셰이크에서는 공개키 기반 인증과 키 교환으로 안전하게 공유 비밀을 만들고, 연결이 성립한 뒤에는 빠른 대칭키 암호로 레코드를 보호합니다.

이 구조를 하이브리드 암호화라고 부를 수 있습니다. 공개키 기술은 신원 확인과 키 합의에 강하고, 대칭키 암호는 대량 데이터 보호에 빠릅니다. TLS는 둘의 장점을 시간순으로 나누어 씁니다.


해시 함수와 MAC

해시 함수(Hash Function)는 임의 길이 데이터를 고정 길이의 값으로 변환합니다. 단, 해시는 “고유한 값”이 아닙니다. 출력 길이가 고정되어 있으므로 이론적으로 충돌은 존재합니다. 좋은 암호학적 해시는 충돌을 찾기 어렵고, 입력이 조금만 바뀌어도 출력이 크게 달라지며, 출력만 보고 입력을 역산하기 어렵도록 설계됩니다.

알고리즘출력 길이현재 실무 판단
MD5128비트충돌 공격 때문에 보안 용도로 사용 금지
SHA-1160비트충돌 공격 때문에 사용 중단 방향
SHA-256256비트널리 쓰이는 SHA-2 계열 해시
SHA-384384비트TLS cipher suite에서도 사용
SHA-512512비트SHA-2 계열의 더 긴 출력
SHA-3다양SHA-2와 다른 구조의 표준 해시

해시만으로는 “누가 만든 값인지”를 증명하지 못합니다. 그래서 메시지 무결성과 인증이 필요할 때는 비밀 키를 함께 쓰는 HMAC 같은 MAC(Message Authentication Code)을 사용합니다.

crypto_basics.py
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}")

    message2 = "Hello, TLS?"
    hash_value2 = hashlib.sha256(message2.encode()).hexdigest()
    print(f"메시지 변경 후 SHA-256: {hash_value2}")

def hmac_demo():
    """HMAC으로 메시지 무결성과 공유 비밀 소유를 함께 확인"""
    key = secrets.token_bytes(32)
    message = b"transfer: 1000 to account 1234"

    mac = hmac.new(key, message, hashlib.sha256).digest()
    print(hmac.compare_digest(mac, hmac.new(key, message, hashlib.sha256).digest()))

    tampered = b"transfer: 9999 to account 5678"
    print(hmac.compare_digest(mac, hmac.new(key, tampered, hashlib.sha256).digest()))

hash_demo()
hmac_demo()

디지털 서명의 원리

디지털 서명(Digital Signature)은 개인키로 서명하고 공개키로 검증하는 기술입니다. “해시값을 개인키로 암호화한다”는 설명은 RSA 일부 형태를 지나치게 단순화한 표현입니다. 더 정확히는 서명 알고리즘이 메시지 또는 메시지 해시와 개인키를 입력으로 받아 서명값을 만들고, 검증자는 공개키로 그 서명이 해당 메시지에 대해 유효한지 확인합니다.

TLS 인증서에서는 이 메커니즘이 핵심적으로 쓰입니다. CA가 인증서 내용에 서명하고, 브라우저는 신뢰 저장소의 CA 공개키로 인증서 체인을 검증합니다. 이후 TLS 핸드셰이크에서는 서버가 인증서의 개인키를 실제로 소유하고 있음을 별도 서명으로 증명합니다.


면접 포인트

질문핵심 답변
대칭키 vs 공개키?대칭키는 같은 비밀 키로 빠르게 데이터 보호, 공개키는 인증·서명·키 교환에 적합
TLS에서 둘 다 쓰는 이유?핸드셰이크로 키를 합의하고, 이후 대칭키 AEAD로 데이터를 빠르게 보호
해시와 HMAC 차이?해시는 공개 계산 가능, HMAC은 비밀 키를 알아야 같은 값을 만들 수 있음
디지털 서명 원리?개인키로 서명하고 공개키로 검증해 무결성, 출처, 부인 방지를 제공

다음 절에서는 이 암호화 기법들이 실제로 어떻게 조합되어 TLS 핸드셰이크를 이루는지 살펴보겠습니다.