-
Notifications
You must be signed in to change notification settings - Fork 0
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
1 parent
eae2b3a
commit 3c290f3
Showing
2 changed files
with
172 additions
and
1 deletion.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,171 @@ | ||
--- | ||
title: "이해하기 쉬운 TLS" | ||
date: 2024-09-18 12:00:00 +0900 | ||
categories: "network" | ||
tags: ["network", "http"] | ||
--- | ||
|
||
초기 웹 통신에서는 제3자가 통신 내용을 엿볼 수 있는 보안 문제가 존재했습니다. 이를 해결하기 위해 1990년대 중반, 넷스케이프(Netscape)는 **SSL**(Secure Sockets Layer) 프로토콜을 개발했습니다. SSL은 클라이언트와 서버 간의 데이터를 암호화하여 외부의 엿보기를 방지하며, **데이터 암호화**, **무결성 검증**, **양측의 신원 인증**을 통해 보안을 강화했습니다. 이로 인해 인터넷 뱅킹과 전자상거래에서 안전한 데이터 전송이 가능해졌습니다. | ||
|
||
하지만 시간이 지남에 따라 **SSL**의 보안 취약점이 드러났습니다. 이를 해결하기 위해 1999년에 **Tim Dierks**와 **Christopher Allen**은 **SSL 3.0**의 후속으로 **TLS**(Transport Layer Security) 1.0을 개발했습니다. **TLS**는 SSL의 후계자로서 더 강력한 보안 기능을 제공하며, SSL의 취약점을 보완하도록 설계되었습니다. 오늘날 **TLS**는 SSL과 호환되며 대부분의 현대 시스템에서 널리 사용되고 있습니다. | ||
|
||
**TLS**는 두 가지 주요 단계로 구성됩니다. 첫 번째는 **핸드셰이크(Handshake)** 단계로, 클라이언트와 서버가 **프로토콜 버전**과 **암호화 키**를 교환하고, 서로의 신원을 확인합니다. 두 번째는 **암호화된 데이터 전송** 단계로, 애플리케이션 데이터가 암호화되어 안전하게 통신이 이루어집니다. | ||
|
||
## 핸드셰이크 (Handshake) | ||
|
||
TLS 핸드셰이크는 클라이언트와 서버 간에 안전한 통신을 설정하기 위한 과정으로, 세션의 암호화 매개변수를 설정하고 TLS 레코드 계층을 통해 안전한 연결을 수립하는 역할을 합니다. | ||
|
||
``` | ||
Client Server | ||
ClientHello --------> | ||
ServerHello | ||
Certificate* | ||
ServerKeyExchange* | ||
CertificateRequest* | ||
<-------- ServerHelloDone | ||
Certificate* | ||
ClientKeyExchange | ||
CertificateVerify* | ||
[ChangeCipherSpec] | ||
Finished --------> | ||
[ChangeCipherSpec] | ||
<-------- Finished | ||
Application Data <-------> Application Data | ||
``` | ||
|
||
### ClientHello | ||
|
||
TLS 핸드셰이크는 클라이언트가 `ClientHello` 메시지를 서버에 전송하면서 시작됩니다. 이 메시지에는 다음 정보가 포함됩니다: | ||
|
||
- **TLS 프로토콜 버전**: 클라이언트가 지원하는 TLS 버전. 예를 들어, TLS 1.2 또는 TLS 1.3. | ||
- **암호화 스위트**: 클라이언트가 지원하는 암호화 알고리즘의 목록. 예를 들어, `ECDHE-RSA-AES256-GCM-SHA384`. | ||
- **압축 방법**: 데이터 압축 방식을 명시. TLS 1.3에서는 압축이 비활성화됨. | ||
- **랜덤 값**: 클라이언트가 생성한 임의 데이터로, 핸드셰이크의 보안성을 높이는 데 사용됩니다. | ||
|
||
암호화 스위트의 조합은 세션의 보안성을 결정하는 중요한 요소입니다. 다음은 자주 사용되는 알고리즘의 설명입니다: | ||
|
||
- **ECDHE (Elliptic Curve Diffie-Hellman Ephemeral)**: 대칭 키를 안전하게 교환하는 알고리즘으로, 각 세션에서 새로운 키를 생성해 보안을 강화합니다. | ||
- **RSA**: 인증서 서명과 키 교환에 사용되는 비대칭 암호화 알고리즘. | ||
- **AES_256_GCM**: 256비트 키를 사용하는 대칭 암호화 알고리즘으로, GCM 모드를 통해 데이터의 기밀성을 보장합니다. | ||
- **SHA384**: 메시지 무결성을 확인하기 위한 해시 함수. | ||
|
||
특히 **ECDHE** 알고리즘은 매 세션마다 새로운 키를 생성하여 보안성을 극대화합니다. 이를 통해 비밀 정보를 직접 공유하지 않고도 동일한 공유 비밀 키를 생성할 수 있습니다. | ||
|
||
- **공개 파라미터 설정**: 클라이언트와 서버는 소수 \( p \)와 원시 근 \( g \)를 공개적으로 선택합니다. | ||
- **비밀 키 생성**: 클라이언트와 서버는 각자 개인 비밀 키 \( a \)와 \( b \)를 생성합니다. | ||
- **공개 키 전송**: 생성된 공개 키를 상대방에게 전송합니다. | ||
- **공유 비밀 키 생성**: 상대방의 공개 키를 사용해 공유 비밀 키를 계산합니다. | ||
|
||
또한 `ClientHello` 메시지에는 몇 가지 확장 기능이 포함될 수 있습니다: | ||
|
||
- **SNI (Server Name Indication)**: 클라이언트가 요청하는 서버의 도메인 이름을 포함하여 서버가 적절한 인증서를 선택할 수 있게 합니다. 이는 여러 도메인을 하나의 IP 주소에서 호스팅할 때 유용합니다. | ||
- **ALPN (Application Layer Protocol Negotiation)**: TLS 핸드셰이크 중 클라이언트와 서버가 사용하려는 애플리케이션 계층 프로토콜을 협상할 수 있게 해줍니다. 클라이언트가 지원하는 프로토콜 목록을 제공하면, 서버는 적합한 프로토콜을 선택하여 응답합니다. | ||
|
||
### ServerHello | ||
|
||
서버는 클라이언트의 `ClientHello` 메시지에 대한 응답으로 `ServerHello` 메시지를 전송합니다. 이 메시지에는 다음 정보가 포함됩니다: | ||
|
||
- **협상된 TLS 프로토콜 버전**: 서버가 지원하는 가장 높은 버전의 TLS. | ||
- **선택된 암호화 스위트**: 클라이언트가 제안한 목록 중 서버가 선택한 암호화 알고리즘 조합. | ||
- **압축 방법**: 서버가 사용할 데이터 압축 방식. | ||
- **서버 랜덤 값**: 서버가 생성한 랜덤 데이터로, 핸드셰이크 과정에서 보안성을 높이는 데 사용됩니다. | ||
|
||
이 단계에서 서버는 선택된 암호화 매개변수를 설정하고, 이후 클라이언트와의 안전한 데이터 전송을 준비합니다. | ||
|
||
### Certificate | ||
|
||
서버는 `Certificate` 메시지를 통해 클라이언트에게 자신을 증명하는 인증서를 전송합니다. 이 인증서는 **X.509 표준**을 따르며, 서버의 공개 키와 신원 정보를 포함합니다. 이를 통해 클라이언트는 서버가 신뢰할 수 있는지 검증할 수 있습니다. 인증서는 신뢰할 수 있는 인증 기관(CA)에 의해 서명되어, 그 진위성과 무결성을 보장합니다. | ||
|
||
X.509 인증서의 주요 구성 요소는 다음과 같습니다: | ||
|
||
```text | ||
Certificate | ||
- Version: 인증서의 버전 | ||
- Serial Number: CA가 할당한 고유 번호 | ||
- Algorithm Identifier: 서명에 사용된 알고리즘 식별자 | ||
- Signature: 인증서의 디지털 서명 | ||
- Issuer: 인증서 발급자(CA) | ||
- Validity: 인증서의 유효 기간 | ||
- Not Before: 유효 기간 시작 날짜 | ||
- Not After: 유효 기간 종료 날짜 | ||
- Subject: 인증서 소유자 | ||
- Subject Public Key Info: 공개 키 정보 | ||
- Public Key Algorithm: 사용된 공개 키 알고리즘 | ||
- Subject Public Key: 소유자의 공개 키 | ||
- Issuer Unique Identifier (Optional): 발급자의 고유 식별자 | ||
- Subject Unique Identifier (Optional): 소유자의 고유 식별자 | ||
- Extensions (Optional): 확장 정보 (예: SAN, Key Usage 등) | ||
Certificate Signature Algorithm: 서명에 사용된 알고리즘 | ||
Certificate Signature: 서명 데이터 | ||
``` | ||
|
||
인증 기관(CA)은 서버 인증서를 발급할 때, 인증서 내용에 디지털 서명을 추가하여 이를 보장합니다. 이 서명은 **PKCS#1 v1.5 패딩**과 같은 알고리즘을 사용하여 데이터를 암호화합니다. 인증서에는 도메인 이름이 **Subject** 필드에 명시되며, **SAN (Subject Alternative Name)** 확장을 통해 여러 도메인을 인증할 수 있습니다. | ||
|
||
인증 체계는 계층적으로 구성되며, 가장 상위에는 **Root CA**가 있습니다. `Root CA`는 자기 서명(self-signed)된 인증서를 보유하고 있으며, 그 하위에 위치한 **Intermediate CA**에게 인증서를 발급합니다. 이로 인해 신뢰의 연쇄(trust chain)가 형성되며, 최종적으로 서버 또는 클라이언트에 도달하게 됩니다. | ||
|
||
- **Root CA**: 신뢰 체계의 최상위에 있는 기관으로, 자기 서명된 인증서를 발급합니다. | ||
- **Intermediate CA**: Root CA의인증을 받은 후 인증서를 발급할 수 있는 기관입니다. | ||
- **Server CA**: 실제 서버에 인증서를 발급하여 통신 보안을 제공합니다. | ||
|
||
### ServerKeyExchange | ||
|
||
서버는 `ServerKeyExchange` 메시지를 전송하여 클라이언트와 공유할 수 있는 키를 교환합니다. 이 메시지에는 다음 정보가 포함됩니다: | ||
|
||
- **서버의 공개 키**: 서버가 사용하는 공개 키, 클라이언트가 암호화된 정보를 서버에 전송할 때 사용됩니다. | ||
- **DH 파라미터**: Diffie-Hellman 키 교환을 위한 파라미터. 이는 클라이언트와 서버 간의 암호화된 키를 생성하는 데 사용됩니다. | ||
|
||
### CertificateRequest | ||
|
||
서버는 클라이언트의 인증서를 요청할 수 있습니다. 이 메시지에는 다음 정보가 포함됩니다: | ||
|
||
- **요청하는 인증서 유형**: 클라이언트 인증에 사용될 인증서의 유형. | ||
- **인증 기관 목록**: 클라이언트가 제공해야 하는 인증서가 발급된 인증 기관의 목록. | ||
|
||
클라이언트 인증은 서버가 클라이언트를 신뢰할 수 있는지 확인하기 위해 사용됩니다. 클라이언트 인증서를 통해 클라이언트는 자신의 신원을 증명할 수 있습니다. | ||
|
||
### ServerHelloDone | ||
|
||
서버는 `ServerHelloDone` 메시지를 전송하여 클라이언트의 응답을 기다립니다. 이 메시지는 서버가 핸드셰이크 과정의 초기 단계를 완료했음을 나타냅니다. | ||
|
||
### Certificate | ||
|
||
클라이언트는 서버와의 통신을 위한 **인증서**를 전송합니다. 클라이언트 인증서는 클라이언트가 서버에 제공할 신뢰할 수 있는 증명서를 의미합니다. | ||
|
||
### ClientKeyExchange | ||
|
||
클라이언트는 `ClientKeyExchange` 메시지를 전송하여 서버와 공유할 비밀 키를 전달합니다. 이 메시지에는 클라이언트가 생성한 **프리마스터 시크릿(Pre-Master Secret)**이 포함됩니다. 이 비밀 키는 세션의 암호화 키를 생성하는 데 사용됩니다. | ||
|
||
### CertificateVerify | ||
|
||
클라이언트는 `CertificateVerify` 메시지를 전송하여 클라이언트 인증서가 유효함을 증명합니다. 이 메시지에는 클라이언트 인증서의 서명이 포함되며, 서버는 이를 통해 클라이언트의 인증서를 검증합니다. | ||
|
||
### ChangeCipherSpec | ||
|
||
클라이언트와 서버는 `ChangeCipherSpec` 메시지를 전송하여 암호화 매개변수를 변경합니다. 이 메시지는 새로운 암호화 키와 매개변수를 적용할 준비가 되었음을 나타냅니다. | ||
|
||
### Finished | ||
|
||
클라이언트와 서버는 `Finished` 메시지를 전송하여 핸드셰이크가 완료되었음을 알립니다. 이 메시지는 핸드셰이크 과정에서 교환된 모든 정보가 무결성을 유지하고 있음을 확인하는 역할을 합니다. | ||
|
||
## 암호화된 데이터 전송 | ||
|
||
핸드셰이크가 완료된 후, 클라이언트와 서버는 암호화된 데이터 전송을 시작합니다. TLS는 **TLS 레코드 계층**을 통해 애플리케이션 데이터를 안전하게 암호화합니다. | ||
|
||
### 레코드 계층 (Record Layer) | ||
|
||
레코드 계층은 암호화된 데이터의 전송을 담당합니다. 이 계층은 전송할 데이터가 적절히 암호화되어 송신되도록 보장하며, 수신된 데이터는 복호화하여 애플리케이션이 처리할 수 있도록 합니다. 레코드 계층의 주요 역할은 다음과 같습니다: | ||
|
||
- **데이터 분할 및 재조합**: 애플리케이션 데이터는 TLS 레코드 계층에서 일정 크기로 분할되며, 수신 측에서는 이를 재조합하여 처리합니다. | ||
- **암호화 및 복호화**: 데이터를 송신하기 전에 암호화하고, 수신 측에서는 이를 복호화하여 처리합니다. | ||
- **무결성 검증**: 데이터의 무결성을 확인하기 위해 메시지 인증 코드(MAC)를 사용합니다. 이를 통해 데이터 전송 중 변경되거나 손상된 경우 이를 감지할 수 있습니다. | ||
|
||
레코드 계층은 애플리케이션 데이터를 다음 단계로 전달하기 전에 적절하게 암호화하고 무결성을 검증합니다. | ||
|
||
TLS는 각 레코드에 **헤더**를 추가하여 데이터 전송 중 오류나 손상을 감지하며, **HMAC** (Hash-based Message Authentication Code)을 사용하여 데이터 무결성을 검증합니다. 송신자는 수신자와 합의한 해시 함수를 이용하여 해시 값을 생성하고, 이를 메시지에 추가하여 전송합니다. 수신자는 메시지와 해시 값을 분리하여, 데이터가 손상되지 않았는지 확인합니다. | ||
|
||
## 참고 문서 | ||
|
||
- [RFC 5246 - The Transport Layer Security](https://datatracker.ietf.org/doc/html/rfc5246) | ||
- [X.509](https://ko.wikipedia.org/wiki/X.509) | ||
- [Luavis' Dev Story - 알아두면 쓸데없는 신비한 TLS](https://luavis.me/server/tls-101) |