```text
Network Working Group T. Dierks
Request for Comments: 5246 Independent
Obsoletes: 3268, 4346, 4366 E. Rescorla
Updates: 4492 RTFM, Inc.
Category: Standards Track August 2008
The Transport Layer Security (TLS) Protocol
Version 1.2
```
---
# **Status of This Memo**
본 문서는 인터넷 커뮤니티를 위한 인터넷 표준 트랙 프로토콜을 명시하고 개선을 위한 논의와 제안을 요청합니다. 이 프로토콜의 표준화 상태 및 상태에 대해서는 "인터넷 공식 프로토콜 표준"\(STD 1\) 최신판을 참조하세요. 이 메모의 배포는 무제한입니다.
---
# **Abstract**
이 문서에서는 TLS\(Transport Layer Security\) 프로토콜 버전 1.2를 지정합니다. TLS 프로토콜은 인터넷을 통한 통신 보안을 제공합니다. 이 프로토콜을 사용하면 클라이언트/서버 응용 프로그램이 도청, 변조 또는 메시지 위조를 방지하도록 설계된 방식으로 통신할 수 있습니다.
---
# **Table of Contents**
```text
1. Introduction ....................................................4
1.1. Requirements Terminology ...................................5
1.2. Major Differences from TLS 1.1 .............................5
2. Goals ...........................................................6
3. Goals of This Document ..........................................7
4. Presentation Language ...........................................7
4.1. Basic Block Size ...........................................7
4.2. Miscellaneous ..............................................8
4.3. Vectors ....................................................8
4.4. Numbers ....................................................9
4.5. Enumerateds ................................................9
4.6. Constructed Types .........................................10
4.6.1. Variants ...........................................10
4.7. Cryptographic Attributes ..................................12
4.8. Constants .................................................14
5. HMAC and the Pseudorandom Function .............................14
6. The TLS Record Protocol ........................................15
6.1. Connection States .........................................16
6.2. Record Layer ..............................................19
6.2.1. Fragmentation ......................................19
6.2.2. Record Compression and Decompression ...............20
6.2.3. Record Payload Protection ..........................21
6.2.3.1. Null or Standard Stream Cipher ............22
6.2.3.2. CBC Block Cipher ..........................22
6.2.3.3. AEAD Ciphers ..............................24
6.3. Key Calculation ...........................................25
7. The TLS Handshaking Protocols ..................................26
7.1. Change Cipher Spec Protocol ...............................27
7.2. Alert Protocol ............................................28
7.2.1. Closure Alerts .....................................29
7.2.2. Error Alerts .......................................30
7.3. Handshake Protocol Overview ...............................33
7.4. Handshake Protocol ........................................37
7.4.1. Hello Messages .....................................38
7.4.1.1. Hello Request .............................38
7.4.1.2. Client Hello ..............................39
7.4.1.3. Server Hello ..............................42
7.4.1.4. Hello Extensions ..........................44
7.4.1.4.1. Signature Algorithms ...........45
7.4.2. Server Certificate .................................47
7.4.3. Server Key Exchange Message ........................50
7.4.4. Certificate Request ................................53
7.4.5. Server Hello Done ..................................55
7.4.6. Client Certificate .................................55
7.4.7. Client Key Exchange Message ........................57
7.4.7.1. RSA-Encrypted Premaster Secret Message ....58
7.4.7.2. Client Diffie-Hellman Public Value ........61
7.4.8. Certificate Verify .................................62
7.4.9. Finished ...........................................63
8. Cryptographic Computations .....................................64
8.1. Computing the Master Secret ...............................64
8.1.1. RSA ................................................65
8.1.2. Diffie-Hellman .....................................65
9. Mandatory Cipher Suites ........................................65
10. Application Data Protocol .....................................65
11. Security Considerations .......................................65
12. IANA Considerations ...........................................65
Appendix A. Protocol Data Structures and Constant Values ..........68
A.1. Record Layer ..............................................68
A.2. Change Cipher Specs Message ...............................69
A.3. Alert Messages ............................................69
A.4. Handshake Protocol ........................................70
A.4.1. Hello Messages .....................................71
A.4.2. Server Authentication and Key Exchange Messages ....72
A.4.3. Client Authentication and Key Exchange Messages ....74
A.4.4. Handshake Finalization Message .....................74
A.5. The Cipher Suite ..........................................75
A.6. The Security Parameters ...................................77
A.7. Changes to RFC 4492 .......................................78
Appendix B. Glossary ..............................................78
Appendix C. Cipher Suite Definitions ..............................83
Appendix D. Implementation Notes ..................................85
D.1. Random Number Generation and Seeding ......................85
D.2. Certificates and Authentication ...........................85
D.3. Cipher Suites .............................................85
D.4. Implementation Pitfalls ...................................85
Appendix E. Backward Compatibility ................................87
E.1. Compatibility with TLS 1.0/1.1 and SSL 3.0 ................87
E.2. Compatibility with SSL 2.0 ................................88
E.3. Avoiding Man-in-the-Middle Version Rollback ...............90
Appendix F. Security Analysis .....................................91
F.1. Handshake Protocol ........................................91
F.1.1. Authentication and Key Exchange ....................91
F.1.1.1. Anonymous Key Exchange ....................91
F.1.1.2. RSA Key Exchange and Authentication .......92
F.1.1.3. Diffie-Hellman Key Exchange with
Authentication ............................92
F.1.2. Version Rollback Attacks ...........................93
F.1.3. Detecting Attacks Against the Handshake Protocol ...94
F.1.4. Resuming Sessions ..................................94
F.2. Protecting Application Data ...............................94
F.3. Explicit IVs ..............................................95
F.4. Security of Composite Cipher Modes ........................95
F.5. Denial of Service .........................................96
F.6. Final Notes ...............................................96
Normative References ..............................................97
Informative References ............................................98
Working Group Information ........................................101
Contributors .....................................................101
```
---
## **1. Introduction**
TLS 프로토콜의 기본 목표는 통신하는 두 응용 프로그램 간에 개인 정보 보호 및 데이터 무결성을 제공하는 것입니다. 프로토콜은 TLS 레코드 프로토콜과 TLS 핸드셰이크 프로토콜의 두 계층으로 구성됩니다. 신뢰할 수 있는 전송 프로토콜\(예: TCP \[TCP\]\) 위에 계층화된 가장 낮은 수준에는 TLS 레코드 프로토콜이 있습니다. TLS 레코드 프로토콜은 두 가지 기본 속성이 있는 연결 보안을 제공합니다.
- 연결은 비공개입니다. 데이터 암호화에는 대칭 암호화가 사용됩니다\(예: AES \[AES\], RC4 \[SCH\] 등\). 이 대칭 암호화의 키는 각 연결에 대해 고유하게 생성되며 다른 프로토콜\(예: TLS 핸드셰이크 프로토콜\)에 의해 협상된 비밀을 기반으로 합니다. Record Protocol은 암호화 없이도 사용할 수 있습니다.
- 연결이 안정적입니다. 메시지 전송에는 키 MAC을 사용한 메시지 무결성 검사가 포함됩니다. MAC 계산에는 보안 해시 함수\(예: SHA-1 등\)가 사용됩니다. 레코드 프로토콜은 MAC 없이 작동할 수 있지만 일반적으로 다른 프로토콜이 보안 매개변수 협상을 위한 전송으로 레코드 프로토콜을 사용하는 동안 이 모드에서만 사용됩니다.
TLS 레코드 프로토콜은 다양한 상위 수준 프로토콜을 캡슐화하는 데 사용됩니다. 캡슐화된 프로토콜 중 하나인 TLS 핸드셰이크 프로토콜을 사용하면 애플리케이션 프로토콜이 첫 번째 데이터 바이트를 전송하거나 수신하기 전에 서버와 클라이언트가 서로를 인증하고 암호화 알고리즘과 암호화 키를 협상할 수 있습니다. TLS 핸드셰이크 프로토콜은 세 가지 기본 속성이 있는 연결 보안을 제공합니다.
- 피어의 신원은 비대칭 또는 공개 키, 암호화\(예: RSA \[RSA\], DSA \[DSS\] 등\)를 사용하여 인증될 수 있습니다. 이 인증은 선택 사항으로 설정할 수 있지만 일반적으로 피어 중 하나 이상에 필수입니다.
- 공유 비밀의 협상은 안전합니다. 협상된 비밀은 도청자가 사용할 수 없으며 인증된 연결의 경우 연결 중간에 자신을 놓을 수 있는 공격자라도 비밀을 얻을 수 없습니다.
- 협상은 신뢰할 수 있습니다. 공격자는 통신 당사자에 의해 감지되지 않고 협상 통신을 수정할 수 없습니다.
TLS의 한 가지 장점은 애플리케이션 프로토콜에 독립적이라는 것입니다. 상위 수준 프로토콜은 TLS 프로토콜 위에 투명하게 계층화될 수 있습니다. 그러나 TLS 표준은 프로토콜이 TLS로 보안을 추가하는 방법을 지정하지 않습니다. TLS 핸드셰이킹을 시작하는 방법과 교환된 인증 인증서를 해석하는 방법에 대한 결정은 TLS 위에서 실행되는 프로토콜의 설계자와 구현자의 판단에 달려 있습니다.
---
### **1.1. Requirements Terminology**
이 문서의 핵심 단어 "MUST", "MUST NOT", "REQUIRED", "SHALL", "SHALL NOT", "SHOULD", "SHOULD NOT", "RECOMMENDED", "MAY" 및 "OPTIONAL"은 다음과 같습니다. RFC 2119 \[REQ\]에 설명된 대로 해석됩니다.
---
### **1.2. Major Differences from TLS 1.1**
이 문서는 특히 암호화 알고리즘 협상에 대한 향상된 유연성을 포함하는 TLS 1.1 \[TLS1.1\] 프로토콜의 개정판입니다. 주요 변경 사항은 다음과 같습니다.
- PRF\(의사 난수 함수\)의 MD5/SHA-1 조합이 암호 제품군 지정 PRF로 대체되었습니다. 이 문서의 모든 암호 제품군은 P\_SHA256을 사용합니다.
- 디지털 서명된 요소의 MD5/SHA-1 조합이 단일 해시로 대체되었습니다. 이제 서명된 요소에는 사용된 해시 알고리즘을 명시적으로 지정하는 필드가 포함됩니다.
- 클라이언트와 서버가 허용할 해시 및 서명 알고리즘을 지정하는 기능이 대폭 정리되었습니다. 이는 또한 이전 버전의 TLS에서 서명 및 해시 알고리즘에 대한 일부 제약 조건을 완화합니다.
- 추가 데이터 모드로 인증된 암호화에 대한 지원이 추가되었습니다.
- TLS 확장 정의와 AES Cipher Suites가 외부 \[TLSEXT\] 및 \[TLSAES\]에서 병합되었습니다.
- EncryptedPreMasterSecret 버전 번호를 더욱 엄격하게 확인합니다.
- 다양한 요구사항을 강화했습니다.
- 이제 verify\_data 길이가 암호화 제품군에 따라 달라집니다\(기본값은 여전히 12\).
- Bleichenbacher/Klima 공격 방어에 대한 설명을 정리했습니다.
- 이제 많은 경우에 경고를 보내야 합니다.
- 인증서 요청 후 사용할 수 있는 인증서가 없으면 클라이언트는 이제 빈 인증서 목록을 보내야 합니다.
- TLS\_RSA\_WITH\_AES\_128\_CBC\_SHA는 이제 암호 제품군을 구현하는 데 필수입니다.
```text
- Added HMAC-SHA256 cipher suites.
```
- IDEA 및 DES 암호화 제품군이 제거되었습니다. 이제 더 이상 사용되지 않으며 별도의 문서에 문서화됩니다.
- SSLv2 이전 버전과 호환되는 hello에 대한 지원은 이제 SHOULD NOT을 전송하는 SHOULD가 아닌 MAY입니다. 지원은 아마도 미래에는 하지 말아야 할 것이 될 것입니다.
- 여러 사례 부문이 동일한 인코딩을 가질 수 있도록 프레젠테이션 언어에 제한된 "fall-through"를 추가했습니다.
- 구현 함정 섹션을 추가했습니다.
- 일반적인 설명 및 편집 작업.
---
## **2. Goals**
TLS 프로토콜의 목표는 우선순위에 따라 다음과 같습니다.
1. 암호화 보안: 두 당사자 간의 보안 연결을 설정하려면 TLS를 사용해야 합니다.
1. 상호 운용성: 독립적인 프로그래머는 서로의 코드에 대한 지식 없이도 암호화 매개변수를 성공적으로 교환할 수 있는 TLS를 활용하는 애플리케이션을 개발할 수 있어야 합니다.
1. 확장성: TLS는 필요에 따라 새로운 공개 키 및 대량 암호화 방법을 통합할 수 있는 프레임워크를 제공하려고 합니다. 이는 또한 두 가지 하위 목표, 즉 새로운 프로토콜을 생성할 필요성을 방지하고\(그리고 가능한 새로운 약점이 도입될 위험을 방지하는 것\) 완전히 새로운 보안 라이브러리를 구현할 필요를 방지하는 것입니다.
1. 상대적 효율성: 암호화 작업은 CPU를 많이 사용하는 경향이 있으며, 특히 공개 키 작업은 더욱 그렇습니다. 이러한 이유로 TLS 프로토콜은 처음부터 설정해야 하는 연결 수를 줄이기 위해 선택적 세션 캐싱 체계를 통합했습니다. 또한 네트워크 활동을 줄이기 위해 주의를 기울였습니다.
---
## **3. Goals of This Document**
이 문서와 TLS 프로토콜 자체는 Netscape에서 게시한 SSL 3.0 프로토콜 사양을 기반으로 합니다. 이 프로토콜과 SSL 3.0의 차이점은 극적이지는 않지만 TLS와 SSL 3.0의 다양한 버전이 상호 운용되지 않을 정도로 중요합니다\(각 프로토콜에는 구현을 이전 버전으로 되돌릴 수 있는 메커니즘이 포함되어 있지만\). 이 문서는 주로 프로토콜을 구현할 독자와 프로토콜의 암호화 분석을 수행하는 독자를 대상으로 작성되었습니다. 사양은 이를 염두에 두고 작성되었으며 두 그룹의 요구 사항을 반영하기 위한 것입니다. 이러한 이유로 알고리즘에 따른 많은 데이터 구조와 규칙은 부록이 아닌 텍스트 본문에 포함되어 있어 이에 대한 접근이 더 쉽습니다.
이 문서는 견고한 보안을 유지하는 데 필요한 특정 정책 영역을 다루지만 서비스 정의나 인터페이스 정의에 대한 세부 정보를 제공하기 위한 것이 아닙니다.
---
## **4. Presentation Language**
이 문서는 외부 표현의 데이터 형식을 다룹니다. 다음과 같은 매우 기본적이고 다소 캐주얼하게 정의된 프레젠테이션 구문이 사용됩니다. 구문은 구조의 여러 소스에서 가져옵니다. 구문과 의도 모두에서 프로그래밍 언어 "C"와 XDR \[XDR\]과 유사하지만 너무 많은 유사점을 도출하는 것은 위험합니다. 이 표현 언어의 목적은 TLS만을 문서화하는 것입니다. 특정 목표 외에는 일반적인 적용이 없습니다.
---
### **4.1. Basic Block Size**
모든 데이터 항목의 표현은 명시적으로 지정됩니다. 기본 데이터 블록 크기는 1바이트\(즉, 8비트\)입니다. 다중 바이트 데이터 항목은 왼쪽에서 오른쪽으로, 위에서 아래로 바이트를 연결한 것입니다. 바이트 스트림에서 멀티바이트 항목\(예제에서는 숫자\)은 다음과 같이 구성됩니다\(C 표기법 사용\).
```text
value = (byte[0] << 8*(n-1)) | (byte[1] << 8*(n-2)) |
... | byte[n-1];
```
다중 바이트 값의 바이트 순서는 일반적인 네트워크 바이트 순서 또는 빅엔디안 형식입니다.
---
### **4.2. Miscellaneous**
주석은 "/\*"로 시작하고 "\*/"로 끝납니다.
선택적 구성 요소는 "\[\[ \]\]" 이중 괄호로 묶어 표시됩니다.
해석되지 않은 데이터를 포함하는 단일 바이트 엔터티는 불투명 유형입니다.
---
### **4.3. Vectors**
벡터\(단일 차원 배열\)는 동종 데이터 요소의 스트림입니다. 벡터의 크기는 문서화 시 지정되거나 런타임까지 지정되지 않은 채로 남아 있을 수 있습니다. 두 경우 모두 길이는 벡터의 요소 수가 아닌 바이트 수를 선언합니다. T 유형의 고정 길이 벡터인 새로운 유형 T'를 지정하는 구문은 다음과 같습니다.
```text
T T'[n];
```
여기서 T'는 데이터 스트림에서 n바이트를 차지하며, 여기서 n은 T 크기의 배수입니다. 벡터의 길이는 인코딩된 스트림에 포함되지 않습니다.
다음 예에서 Datum은 프로토콜이 해석하지 않는 3개의 연속 바이트로 정의되는 반면, Data는 3개의 연속 Datum으로 총 9바이트를 사용합니다.
```text
opaque Datum[3]; /* three uninterpreted bytes */
Datum Data[9]; /* 3 consecutive 3 byte vectors */
```
가변 길이 벡터는 <floor..ceiling\> 표기법을 사용하여 유효한 길이의 하위 범위를 지정하여 정의됩니다. 이것이 인코딩되면 실제 길이는 바이트 스트림에서 벡터의 내용보다 앞에 옵니다. 길이는 벡터의 지정된 최대\(천장\) 길이를 유지하는 데 필요한 만큼의 바이트를 소비하는 숫자 형식입니다. 실제 길이 필드가 0인 가변 길이 벡터를 빈 벡터라고 합니다.
```text
T T'<floor..ceiling>;
```
다음 예에서 필수는 불투명 유형의 300\~400바이트를 포함해야 하는 벡터입니다. 결코 비워둘 수 없습니다. 실제 길이 필드는 값 400을 나타내는 데 충분한 uint16이라는 2바이트를 사용합니다\(섹션 4.4 참조\). 반면에 Long은 최대 800바이트의 데이터 또는 400개의 uint16 요소를 나타낼 수 있으며 비어 있을 수 있습니다. 인코딩에는 다음이 포함됩니다.
벡터 앞에 추가되는 2바이트 실제 길이 필드입니다. 인코딩된 벡터의 길이는 단일 요소 길이의 짝수 배수여야 합니다. 예를 들어 uint16의 17바이트 벡터는 불법입니다.
```text
opaque mandatory<300..400>;
/* length field is 2 bytes, cannot be empty */
uint16 longer<0..800>;
/* zero to 400 16-bit unsigned integers */
```
---
### **4.4. Numbers**
기본 숫자 데이터 유형은 부호 없는 바이트\(uint8\)입니다. 모든 더 큰 숫자 데이터 유형은 섹션 4.1에 설명된 대로 연결된 고정 길이 바이트 시리즈로 구성되며 역시 부호가 없습니다. 다음 숫자 유형이 사전 정의되어 있습니다.
```text
uint8 uint16[2];
uint8 uint24[3];
uint8 uint32[4];
uint8 uint64[8];
```
사양의 여기와 다른 곳의 모든 값은 네트워크 바이트\(빅 엔디안\) 순서로 저장됩니다. 16진수 바이트 01 02 03 04로 표시되는 uint32는 10진수 값 16909060과 동일합니다.
어떤 경우에는\(예: DH 매개변수\) 정수를 불투명 벡터로 표시해야 합니다. 그러한 경우에는 부호 없는 정수로 표시됩니다\(즉, 최상위 비트가 설정되더라도 선행 0 옥텟은 필요하지 않습니다\).
---
### **4.5. Enumerateds**
enum이라는 추가적인 희소 데이터 유형을 사용할 수 있습니다. enum 유형의 필드는 정의에 선언된 값만 가정할 수 있습니다. 각 정의는 다른 유형입니다. 동일한 유형의 열거형만 할당하거나 비교할 수 있습니다. 다음 예에 설명된 것처럼 열거형의 모든 요소에는 값이 할당되어야 합니다. 열거된 요소는 순서가 지정되어 있지 않으므로 순서에 관계없이 고유한 값을 할당할 수 있습니다.
```text
enum { e1(v1), e2(v2), ... , en(vn) [[, (n)]] } Te;
```
열거형은 정의된 최대 서수 값만큼 바이트 스트림에서 많은 공간을 차지합니다. 다음 정의에서는 Color 유형의 필드를 전달하는 데 1바이트가 사용됩니다.
```text
enum { red(3), blue(5), white(7) } Color;
```
불필요한 요소를 정의하지 않고 너비 정의를 강제하기 위해 선택적으로 관련 태그 없이 값을 지정할 수 있습니다.
다음 예에서 Taste는 데이터 스트림에서 2바이트를 사용하지만 값은 1, 2 또는 4만 가정할 수 있습니다.
```text
enum { sweet(1), sour(2), bitter(4), (32000) } Taste;
```
열거형 요소의 이름은 정의된 유형 내에서 범위가 지정됩니다. 첫 번째 예에서 열거형의 두 번째 요소에 대한 정규화된 참조는 Color.blue입니다. 과제의 대상이 잘 명시되어 있으면 그러한 자격은 필요하지 않습니다.
```text
Color color = Color.blue; /* overspecified, legal */
Color color = blue; /* correct, type implicit */
```
외부 표현으로 변환되지 않는 열거형의 경우 숫자 정보가 생략될 수 있습니다.
```text
enum { low, medium, high } Amount;
```
---
### **4.6. Constructed Types**
편의를 위해 구조 유형은 기본 유형에서 구성될 수 있습니다. 각 사양은 새롭고 고유한 유형을 선언합니다. 정의 구문은 C의 구문과 매우 유사합니다.
```text
struct {
T1 f1;
T2 f2;
...
Tn fn;
} [[T]];
```
구조 내의 필드는 열거형에 사용할 수 있는 것과 매우 유사한 구문을 사용하여 유형 이름을 사용하여 한정될 수 있습니다. 예를 들어, T.f2는 이전 선언의 두 번째 필드를 나타냅니다. 구조 정의가 포함될 수 있습니다.
---
#### **4.6.1. Variants**
정의된 구조에는 환경 내에서 사용 가능한 일부 지식을 기반으로 하는 변형이 있을 수 있습니다. 선택기는 구조가 정의하는 가능한 변형을 정의하는 열거형 유형이어야 합니다. 선택 항목에 선언된 열거형의 모든 요소에 대한 케이스 암이 있어야 합니다. 케이스 암에는 제한적인 폴스루가 있습니다. 두 케이스 암이 사이에 필드 없이 바로 연속해서 따라오는 경우
둘 다 동일한 필드를 포함합니다. 따라서 아래 예에서 "orange"와 "banana"는 모두 V2를 포함합니다. 이는 TLS 1.2의 새로운 구문입니다.
변형 구조의 본문에는 참조용 라벨이 제공될 수 있습니다. 런타임 시 변형이 선택되는 메커니즘은 표시 언어에 의해 규정되지 않습니다.
```text
struct {
T1 f1;
T2 f2;
....
Tn fn;
select (E) {
case e1: Te1;
case e2: Te2;
case e3: case e4: Te3;
....
case en: Ten;
} [[fv]];
} [[Tv]];
```
예를 들어:
```text
enum { apple, orange, banana } VariantTag;
struct {
uint16 number;
opaque string<0..10>; /* variable length */
} V1;
struct {
uint32 number;
opaque string[10]; /* fixed length */
} V2;
struct {
select (VariantTag) { /* value of selector is implicit */
case apple:
V1; /* VariantBody, tag = apple */
case orange:
case banana:
V2; /* VariantBody, tag = orange or banana */
} variant_body; /* optional label on variant */
} VariantRecord;
```
---
### **4.7. Cryptographic Attributes**
디지털 서명, 스트림 암호 암호화, 블록 암호 암호화, 추가 데이터를 사용한 인증된 암호화\(AEAD\) 암호화, 공개 키 암호화 등 5가지 암호화 작업은 디지털 서명, 스트림 암호화, 블록 암호화, 판독 암호화로 지정됩니다. 및 공개 키로 암호화됩니다. 필드의 암호화 처리는 필드 유형 지정 앞에 적절한 키워드 지정을 추가하여 지정됩니다. 암호화 키는 현재 세션 상태에 의해 암시됩니다\(섹션 6.1 참조\).
디지털 서명된 요소는 DigitallySigned 구조체로 인코딩됩니다.
```text
struct {
SignatureAndHashAlgorithm algorithm;
opaque signature<0..2^16-1>;
} DigitallySigned;
```
알고리즘 필드는 사용된 알고리즘을 지정합니다\(이 필드의 정의는 섹션 7.4.1.4.1 참조\). 알고리즘 필드의 도입은 이전 버전과의 변경 사항입니다. 서명은 요소의 콘텐츠에 대해 해당 알고리즘을 사용하는 디지털 서명입니다. 내용 자체는 와이어에 나타나지 않고 단순히 계산됩니다. 서명의 길이는 서명 알고리즘과 키에 의해 지정됩니다.
RSA 서명에서 불투명 벡터에는 \[PKCS1\]에 정의된 RSASSA-PKCS1-v1\_5 서명 체계를 사용하여 생성된 서명이 포함됩니다. \[PKCS1\]에서 논의된 것처럼 DigestInfo는 DER로 인코딩된 \[X680\] \[X690\]이어야 합니다. 매개변수가 없는 해시 알고리즘\(SHA-1 포함\)의 경우 DigestInfo.AlgorithmIdentifier.parameters 필드는 NULL이어야 하지만 구현에서는 매개변수가 없는 것과 NULL 매개변수가 있는 것을 모두 허용해야 합니다. 이전 버전의 TLS는 DigestInfo 인코딩을 포함하지 않은 다른 RSA 서명 체계를 사용했습니다.
DSA에서는 SHA-1 해시의 20바이트가 추가 해싱 없이 디지털 서명 알고리즘을 통해 직접 실행됩니다. 그러면 r과 s라는 두 값이 생성됩니다. DSA 서명은 위와 같이 불투명한 벡터이며 그 내용은 다음의 DER 인코딩입니다.
```text
Dss-Sig-Value ::= SEQUENCE {
r INTEGER,
s INTEGER
}
```
참고: 현재 용어에서 DSA는 디지털 서명 알고리즘을 나타내고 DSS는 NIST 표준을 나타냅니다. 원래 SSL 및 TLS 사양에서는 "DSS"가 보편적으로 사용되었습니다. 이 문서에서는 알고리즘을 참조하기 위해 "DSA"를 사용하고, 표준을 참조하기 위해 "DSS"를 사용하며, 기록 연속성을 위해 코드 포인트 정의에서 "DSS"를 사용합니다.
스트림 암호 암호화에서 일반 텍스트는 암호화된 보안 키 의사 난수 생성기에서 생성된 동일한 양의 출력과 배타적 OR로 연결됩니다.
블록 암호 암호화에서는 모든 일반 텍스트 블록이 암호 텍스트 블록으로 암호화됩니다. 모든 블록 암호 암호화는 CBC\(Cipher Block Chaining\) 모드로 수행되며, 블록 암호화되는 모든 항목은 암호 블록 길이의 정확한 배수가 됩니다.
AEAD 암호화에서는 일반 텍스트가 동시에 암호화되고 무결성이 보호됩니다. 입력은 임의의 길이일 수 있으며, 무결성 검사 값을 수용하기 위해 일반적으로 입력된 출력이 입력보다 큽니다.
공개 키 암호화에서는 공개 키 알고리즘을 사용하여 일치하는 개인 키로만 해독할 수 있는 방식으로 데이터를 암호화합니다. 공개 키로 암호화된 요소는 불투명 벡터 <0..2^16-1\>로 인코딩됩니다. 여기서 길이는 암호화 알고리즘과 키에 의해 지정됩니다.
RSA 암호화는 \[PKCS1\]에 정의된 RSAES-PKCS1-v1\_5 암호화 체계를 사용하여 수행됩니다.
다음 예에서는
```text
stream-ciphered struct {
uint8 field1;
uint8 field2;
digitally-signed opaque {
uint8 field3<0..255>;
uint8 field4;
};
} UserType;
```
내부 구조체\(field3 및 field4\)의 내용은 서명/해시 알고리즘의 입력으로 사용되며 전체 구조는 스트림 암호로 암호화됩니다. 이 구조의 길이\(바이트\)는 field1 및 field2의 2바이트, 서명 및 해시 알고리즘의 2바이트, 서명 길이의 2바이트, 서명 출력의 길이를 더한 것과 같습니다.
연산. 서명에 사용된 알고리즘과 키는 이 구조를 인코딩하거나 디코딩하기 전에 알려져 있기 때문에 서명의 길이가 알려져 있습니다.
---
### **4.8. Constants**
유형이 지정된 상수는 원하는 유형의 기호를 선언하고 값을 할당하여 사양 목적으로 정의할 수 있습니다.
과소 지정된 유형\(불투명, 가변 길이 벡터 및 불투명을 포함하는 구조체\)에는 값을 할당할 수 없습니다. 다중 요소 구조 또는 벡터의 필드는 생략될 수 없습니다.
예를 들어:
```text
struct {
uint8 f1;
uint8 f2;
} Example1;
Example1 ex1 = {1, 4}; /* assigns f1 = 1, f2 = 4 */
```
---
## **5. HMAC and the Pseudorandom Function**
TLS 레코드 계층은 키가 있는 MAC\(메시지 인증 코드\)을 사용하여 메시지 무결성을 보호합니다. 이 문서에 정의된 암호 제품군은 해시 함수를 기반으로 하는 \[HMAC\]에 설명된 HMAC라는 구성을 사용합니다. 필요한 경우 다른 암호화 제품군은 자체 MAC 구성을 정의할 수 있습니다.
또한 키 생성 또는 검증을 위해 비밀을 데이터 블록으로 확장하려면 구성이 필요합니다. 이 PRF\(의사 난수 함수\)는 비밀, 시드 및 식별 레이블을 입력으로 사용하여 임의 길이의 출력을 생성합니다.
이 섹션에서는 HMAC를 기반으로 하나의 PRF를 정의합니다. SHA-256 해시 기능이 포함된 이 PRF는 이 문서와 TLS 1.2가 협상될 때 이 문서 이전에 게시된 TLS 문서에 정의된 모든 암호화 제품군에 사용됩니다. 새로운 암호 모음은 PRF를 명시적으로 지정해야 하며 일반적으로 SHA-256 또는 더 강력한 표준 해시 기능과 함께 TLS PRF를 사용해야 합니다.
먼저 단일 해시 함수를 사용하여 비밀과 시드를 임의의 양의 출력으로 확장하는 데이터 확장 함수 P\_hash\(secret, data\)를 정의합니다.
```text
P_hash(secret, seed) = HMAC_hash(secret, A(1) + seed) +
HMAC_hash(secret, A(2) + seed) +
HMAC_hash(secret, A(3) + seed) + ...
```
여기서 +는 연결을 나타냅니다.
A\(\)는 다음과 같이 정의됩니다.
```text
A(0) = seed
A(i) = HMAC_hash(secret, A(i-1))
```
P\_hash는 필요한 양의 데이터를 생성하는 데 필요한 만큼 반복될 수 있습니다. 예를 들어, P\_SHA256을 사용하여 80바이트의 데이터를 생성하는 경우 A\(3\)을 통해 3번 반복하여 96바이트의 출력 데이터를 생성해야 합니다. 그런 다음 최종 반복의 마지막 16바이트가 삭제되고 80바이트의 출력 데이터가 남습니다.
TLS의 PRF는 다음과 같이 비밀에 P\_hash를 적용하여 생성됩니다.
```text
PRF(secret, label, seed) = P_<hash>(secret, label + seed)
```
레이블은 ASCII 문자열입니다. 길이 바이트나 후행 널 문자 없이 제공된 정확한 형식으로 포함되어야 합니다. 예를 들어 "slithy toves"라는 라벨은 다음 바이트를 해싱하여 처리됩니다.
```text
73 6C 69 74 68 79 20 74 6F 76 65 73
```
---
## **6. The TLS Record Protocol**
TLS 레코드 프로토콜은 계층화된 프로토콜입니다. 각 계층에서 메시지에는 길이, 설명 및 내용에 대한 필드가 포함될 수 있습니다. 레코드 프로토콜은 전송할 메시지를 취하고, 데이터를 관리 가능한 블록으로 조각화하고, 선택적으로 데이터를 압축하고, MAC를 적용하고, 암호화하고, 결과를 전송합니다. 수신된 데이터는 암호 해독, 확인, 압축 해제, 재조립된 후 상위 수준 클라이언트로 전달됩니다.
이 문서에서는 기록 프로토콜을 사용하는 네 가지 프로토콜, 즉 핸드셰이크 프로토콜, 경고 프로토콜, 암호 사양 변경 프로토콜 및 애플리케이션 데이터 프로토콜에 대해 설명합니다. TLS 프로토콜의 확장을 허용하기 위해 레코드 프로토콜에서 추가 레코드 콘텐츠 유형을 지원할 수 있습니다. 새로운 기록 콘텐츠 유형 값은 섹션 12에 설명된 대로 TLS 콘텐츠 유형 레지스트리의 IANA에 의해 할당됩니다.
구현은 일부 확장에 의해 협상되지 않는 한 이 문서에 정의되지 않은 레코드 유형을 전송해서는 안 됩니다. TLS 구현이 예상치 못한 레코드 유형을 수신하는 경우 예기치 않은\_메시지 경고를 보내야 합니다\(MUST\).
TLS를 통해 사용하도록 설계된 모든 프로토콜은 이에 대한 가능한 모든 공격을 처리하도록 신중하게 설계되어야 합니다. 실제적으로 이는 프로토콜 설계자가 TLS가 제공하는 보안 속성과 제공하지 않는 보안 속성이 무엇인지, 그리고 후자에 안전하게 의존할 수 없는지 알아야 함을 의미합니다.
특히 레코드의 유형과 길이는 암호화로 보호되지 않습니다. 이 정보 자체가 민감한 정보인 경우 애플리케이션 설계자는 정보 누출을 최소화하기 위한 조치\(패딩, 트래픽 커버\)를 취할 수 있습니다.
---
### **6.1. Connection States**
TLS 연결 상태는 TLS 레코드 프로토콜의 운영 환경입니다. 압축 알고리즘, 암호화 알고리즘, MAC 알고리즘을 지정합니다. 또한 이러한 알고리즘에 대한 매개변수는 읽기 및 쓰기 방향의 연결을 위한 MAC 키와 대량 암호화 키로 알려져 있습니다. 논리적으로 항상 4가지 연결 상태, 즉 현재 읽기 및 쓰기 상태와 보류 중인 읽기 및 쓰기 상태가 있습니다. 모든 레코드는 현재 읽기 및 쓰기 상태에서 처리됩니다. 보류 상태에 대한 보안 매개변수는 TLS 핸드셰이크 프로토콜에 의해 설정될 수 있으며 ChangeCipherSpec은 보류 상태 중 하나를 선택적으로 현재 상태로 만들 수 있습니다. 이 경우 적절한 현재 상태는 삭제되고 보류 상태로 대체됩니다. 그런 다음 보류 상태는 빈 상태로 다시 초기화됩니다. 보안 매개변수로 초기화되지 않은 상태를 현재 상태로 만드는 것은 불법입니다. 초기 현재 상태에서는 항상 암호화, 압축 또는 MAC가 사용되지 않음을 지정합니다.
TLS 연결 읽기 및 쓰기 상태에 대한 보안 매개변수는 다음 값을 제공하여 설정됩니다.
연결 종료 - 이 엔터티가 이 연결에서 "클라이언트"로 간주되는지 아니면 "서버"로 간주되는지 여부입니다.
PRF 알고리즘 - 마스터 보안에서 키를 생성하는 데 사용되는 알고리즘입니다\(섹션 5 및 6.3 참조\).
대량 암호화 알고리즘 - 대량 암호화에 사용되는 알고리즘입니다. 이 사양에는 이 알고리즘의 키 크기\(블록, 스트림 또는 AEAD 암호인지 여부\), 암호의 블록 크기\(해당하는 경우\), 명시적 및 암시적 초기화 벡터\(또는 nonce\)의 길이가 포함됩니다.
MAC 알고리즘 - 메시지 인증에 사용되는 알고리즘입니다. 이 사양에는 MAC 알고리즘에서 반환되는 값의 크기가 포함됩니다.
압축 알고리즘 - 데이터 압축에 사용되는 알고리즘입니다. 이 사양에는 알고리즘이 압축을 수행하는 데 필요한 모든 정보가 포함되어야 합니다.
마스터 비밀 - 연결에 있는 두 피어 간에 공유되는 48바이트 비밀입니다.
클라이언트 무작위 - 클라이언트가 제공하는 32바이트 값입니다.
서버 무작위 - 서버에서 제공하는 32바이트 값입니다.
- 이러한 매개변수는 표시 언어에서 다음과 같이 정의됩니다.
```text
enum { server, client } ConnectionEnd;
enum { tls_prf_sha256 } PRFAlgorithm;
enum { null, rc4, 3des, aes }
BulkCipherAlgorithm;
enum { stream, block, aead } CipherType;
enum { null, hmac_md5, hmac_sha1, hmac_sha256,
hmac_sha384, hmac_sha512} MACAlgorithm;
enum { null(0), (255) } CompressionMethod;
/* The algorithms specified in CompressionMethod, PRFAlgorithm,
BulkCipherAlgorithm, and MACAlgorithm may be added to. */
struct {
ConnectionEnd entity;
PRFAlgorithm prf_algorithm;
BulkCipherAlgorithm bulk_cipher_algorithm;
CipherType cipher_type;
uint8 enc_key_length;
uint8 block_length;
uint8 fixed_iv_length;
uint8 record_iv_length;
MACAlgorithm mac_algorithm;
uint8 mac_length;
uint8 mac_key_length;
CompressionMethod compression_algorithm;
opaque master_secret[48];
opaque client_random[32];
opaque server_random[32];
} SecurityParameters;
```
레코드 레이어는 보안 매개변수를 사용하여 다음 6개 항목을 생성합니다\(일부는 모든 암호에 필요하지 않으므로 비어 있음\).
```text
client write MAC key
server write MAC key
client write encryption key
server write encryption key
client write IV
server write IV
```
클라이언트 쓰기 매개변수는 레코드를 수신하고 처리할 때 서버에서 사용되며 그 반대의 경우도 마찬가지입니다. 보안 매개변수에서 이러한 항목을 생성하는 데 사용되는 알고리즘은 섹션 6.3에 설명되어 있습니다.
보안 매개변수가 설정되고 키가 생성되면 연결 상태를 현재 상태로 만들어 인스턴스화할 수 있습니다. 이러한 현재 상태는 처리된 각 레코드에 대해 업데이트되어야 합니다. 각 연결 상태에는 다음 요소가 포함됩니다.
압축 상태 - 압축 알고리즘의 현재 상태입니다.
암호 상태 - 암호화 알고리즘의 현재 상태입니다. 이는 해당 연결에 대해 예약된 키로 구성됩니다. 스트림 암호의 경우 여기에는 스트림이 데이터를 계속 암호화하거나 해독하는 데 필요한 모든 상태 정보도 포함됩니다.
MAC 키 - 위에서 생성된 이 연결의 MAC 키입니다.
시퀀스 번호 - 각 연결 상태에는 읽기 및 쓰기 상태에 대해 별도로 유지되는 시퀀스 번호가 포함됩니다. 연결 상태가 활성 상태가 될 때마다 시퀀스 번호는 0으로 설정되어야 합니다. 시퀀스 번호는 uint64 유형이며 2^64-1을 초과할 수 없습니다. 시퀀스 번호는 줄 바꿈되지 않습니다. TLS 구현이 시퀀스 번호를 래핑해야 하는 경우 대신 재협상해야 합니다. 시퀀스 번호는 각 레코드 이후에 증가합니다. 특히 특정 연결 상태에서 전송된 첫 번째 레코드는 시퀀스 번호 0을 사용해야 합니다.
---
### **6.2. Record Layer**
TLS 레코드 계층은 임의 크기의 비어 있지 않은 블록으로 상위 계층으로부터 해석되지 않은 데이터를 수신합니다.
---
#### **6.2.1. Fragmentation**
레코드 계층은 정보 블록을 2^14바이트 이하의 청크로 데이터를 전달하는 TLSPlaintext 레코드로 조각화합니다. 클라이언트 메시지 경계는 레코드 계층에서 유지되지 않습니다. 즉, 동일한 ContentType의 여러 클라이언트 메시지가 단일 TLSPlaintext 레코드로 통합될 수 있거나 단일 메시지가 여러 레코드에 걸쳐 조각화될 수 있습니다.
```text
struct {
uint8 major;
uint8 minor;
} ProtocolVersion;
enum {
change_cipher_spec(20), alert(21), handshake(22),
application_data(23), (255)
} ContentType;
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
```
유형 - 포함된 조각을 처리하는 데 사용되는 상위 수준 프로토콜입니다.
버전 - 사용 중인 프로토콜의 버전입니다. 이 문서에서는 버전 { 3, 3 }을 사용하는 TLS 버전 1.2에 대해 설명합니다. 버전 값 3.3은 TLS 1.0에 대한 {3, 1} 사용에서 파생된 기록입니다. \(부록 A.1 참조\) 여러 버전의 TLS를 지원하는 클라이언트는 ServerHello를 수신하기 전에 어떤 버전이 사용될지 알 수 없습니다. ClientHello에 사용해야 하는 레코드 계층 버전 번호에 대한 논의는 부록 E를 참조하세요.
길이 - 다음 TLSPlaintext.fragment의 길이\(바이트\)입니다. 길이는 2^14를 초과하면 안 됩니다.
조각 - 애플리케이션 데이터입니다. 이 데이터는 투명하며 유형 필드에 지정된 상위 수준 프로토콜에 의해 처리되는 독립적인 블록으로 처리됩니다.
구현 시 Handshake, Alert 또는 ChangeCipherSpec 콘텐츠 유형의 길이가 0인 조각을 보내서는 안 됩니다. 길이가 0인 응용 프로그램 데이터 조각은 트래픽 분석 대책으로 잠재적으로 유용하므로 전송될 수 있습니다.
참고: 다양한 TLS 레코드 계층 콘텐츠 유형의 데이터가 인터리브될 수 있습니다. 애플리케이션 데이터는 일반적으로 다른 콘텐츠 유형보다 전송 우선순위가 낮습니다. 그러나 기록은 기록 계층에 의해 보호되는 순서와 동일한 순서로 네트워크에 전달되어야 합니다. 수신자는 연결의 첫 번째 핸드셰이크 이후의 핸드셰이크 중에 인터리빙된 애플리케이션 계층 트래픽을 수신하고 처리해야 합니다.
---
#### **6.2.2. Record Compression and Decompression**
모든 레코드는 현재 세션 상태에 정의된 압축 알고리즘을 사용하여 압축됩니다. 항상 활성 압축 알고리즘이 있습니다. 그러나 처음에는 CompressionMethod.null로 정의됩니다. 압축 알고리즘은 TLSPlaintext 구조를 TLSCompressed 구조로 변환합니다. 압축 기능은 연결 상태가 활성화될 때마다 기본 상태 정보로 초기화됩니다. \[RFC3749\]는 TLS에 대한 압축 알고리즘을 설명합니다.
압축은 무손실이어야 하며 콘텐츠 길이를 1024바이트 이상 늘릴 수 없습니다. 압축 해제 기능이 2^14바이트를 초과하는 길이로 압축을 해제하는 TLSCompressed.fragment를 발견하는 경우 치명적인 압축 해제 실패 오류를 보고해야 합니다.
```text
struct {
ContentType type; /* same as TLSPlaintext.type */
ProtocolVersion version;/* same as TLSPlaintext.version */
uint16 length;
opaque fragment[TLSCompressed.length];
} TLSCompressed;
```
길이 - 다음 TLSCompressed.fragment의 길이\(바이트\)입니다. 길이는 2^14 + 1024를 초과하면 안 됩니다.
조각 - TLSPlaintext.fragment의 압축된 형식입니다.
- 참고: CompressionMethod.null 작업은 ID 작업입니다. 필드는 변경되지 않습니다.
- 구현 참고 사항: 압축 해제 기능은 메시지가 내부 버퍼 오버플로를 일으키지 않도록 하는 역할을 합니다.
---
#### **6.2.3. Record Payload Protection**
- 암호화 및 MAC 기능은 TLSCompressed 구조를 TLSCiphertext로 변환합니다. 암호 해독 기능은 프로세스를 반대로 수행합니다. 레코드의 MAC에는 누락된 메시지, 추가 메시지 또는 반복된 메시지를 감지할 수 있도록 시퀀스 번호도 포함되어 있습니다.
```text
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
select (SecurityParameters.cipher_type) {
case stream: GenericStreamCipher;
case block: GenericBlockCipher;
case aead: GenericAEADCipher;
} fragment;
} TLSCiphertext;
```
type - 유형 필드는 TLSCompressed.type과 동일합니다.
version - 버전 필드는 TLSCompressed.version과 동일합니다.
길이 - 다음 TLSCiphertext.fragment의 길이\(바이트\)입니다. 길이는 2^14 + 2048을 초과하면 안 됩니다.
조각 - MAC을 사용하는 TLSCompressed.fragment의 암호화된 형식입니다.
---
##### **6.2.3.1. Null or Standard Stream Cipher**
스트림 암호\(BulkCipherAlgorithm.null 포함, 부록 A.6 참조\)는 TLSCompressed.fragment 구조를 스트림 TLSCiphertext.fragment 구조로 변환합니다.
```text
stream-ciphered struct {
opaque content[TLSCompressed.length];
opaque MAC[SecurityParameters.mac_length];
} GenericStreamCipher;
```
MAC은 다음과 같이 생성됩니다.
```text
MAC(MAC_write_key, seq_num +
TLSCompressed.type +
TLSCompressed.version +
TLSCompressed.length +
TLSCompressed.fragment);
```
여기서 "+"는 연결을 나타냅니다.
seq\_num - 이 레코드의 시퀀스 번호입니다.
MAC - SecurityParameters.mac\_algorithm에 지정된 MAC 알고리즘입니다.
MAC은 암호화 전에 계산됩니다. 스트림 암호는 MAC을 포함한 전체 블록을 암호화합니다. 동기화 벡터\(예: RC4\)를 사용하지 않는 스트림 암호의 경우 한 레코드 끝의 스트림 암호 상태가 후속 패킷에서 단순히 사용됩니다. 암호화 제품군이 TLS\_NULL\_WITH\_NULL\_NULL인 경우 암호화는 ID 작업으로 구성됩니다\(즉, 데이터가 암호화되지 않고 MAC 크기가 0이므로 MAC가 사용되지 않음을 의미함\). 널 및 스트림 암호 모두의 경우 TLSCiphertext.length는 TLSCompressed.length에 SecurityParameters.mac\_length를 더한 값입니다.
---
##### **6.2.3.2. CBC Block Cipher**
블록 암호\(예: 3DES 또는 AES\)의 경우 암호화 및 MAC 기능은 TLSCompressed.fragment 구조를 블록 TLSCiphertext.fragment 구조로 변환합니다.
```text
struct {
opaque IV[SecurityParameters.record_iv_length];
block-ciphered struct {
opaque content[TLSCompressed.length];
opaque MAC[SecurityParameters.mac_length];
uint8 padding[GenericBlockCipher.padding_length];
uint8 padding_length;
};
} GenericBlockCipher;
```
MAC는 섹션 6.2.3.1에 설명된 대로 생성됩니다.
IV - 초기화 벡터\(IV\)는 무작위로 선택되어야 하며 예측할 수 없어야 합니다. 1.1 이전 버전의 TLS에는 IV 필드가 없었고 이전 레코드의 마지막 암호문 블록\("CBC 잔여물"\)이 IV로 사용되었습니다. 이는 \[CBCATT\]에 설명된 공격을 방지하기 위해 변경되었습니다. 블록 암호의 경우 IV 길이는 SecurityParameters.record\_iv\_length이며, 이는 SecurityParameters.block\_size와 동일합니다.
패딩\(padding\) - 일반 텍스트의 길이가 블록 암호 블록 길이의 정수배가 되도록 추가되는 패딩입니다. 패딩의 길이는 TLSCiphertext.length가 블록 길이의 정수배가 되는 한 최대 255바이트일 수 있습니다. 교환된 메시지의 길이 분석을 기반으로 하는 프로토콜에 대한 공격을 좌절시키려면 필요한 것보다 긴 길이가 바람직할 수 있습니다. 패딩 데이터 벡터의 각 uint8은 반드시 패딩 길이 값으로 채워져야 합니다. 수신자는 이 패딩을 확인해야 하며 패딩 오류를 나타내기 위해 bad\_record\_mac 경고를 사용해야 합니다.
padding\_length - 패딩 길이는 GenericBlockCipher 구조의 전체 크기가 암호 블록 길이의 배수가 되도록 해야 합니다. 유효한 값의 범위는 0부터 255까지입니다. 이 길이는 padding\_length 필드 자체를 제외한 패딩 필드의 길이를 지정합니다.
암호화된 데이터 길이\(TLSCiphertext.length\)는 SecurityParameters.block\_length, TLSCompressed.length, SecurityParameters.mac\_length 및 padding\_length의 합보다 1 더 큽니다.
예: 블록 길이가 8바이트, 콘텐츠 길이\(TLSCompressed.length\)가 61바이트, MAC 길이가 20바이트인 경우 패딩 전 길이는 82바이트입니다\(여기에는
IV. 따라서 전체 길이를 8바이트\(블록 길이\)의 짝수 배수로 만들려면 패딩 길이 모듈로 8이 6과 같아야 합니다. 패딩 길이는 6, 14, 22 등이 될 수 있으며 254까지 가능합니다. 패딩 길이가 필요한 최소값인 6인 경우 패딩은 각각 값 6을 포함하는 6바이트가 됩니다. 따라서 패딩의 마지막 8옥텟은 블록 암호화 이전의 GenericBlockCipher는 xx 06 06 06 06 06 06 06입니다. 여기서 xx는 MAC의 마지막 옥텟입니다.
참고: CBC 모드\(암호 블록 체인\)의 블록 암호를 사용하는 경우 암호 텍스트가 전송되기 전에 레코드의 전체 일반 텍스트를 아는 것이 중요합니다. 그렇지 않으면 공격자가 \[CBCATT\]에 설명된 공격을 수행하는 것이 가능합니다.
구현 참고 사항: Canvel et al. \[CBCTIME\]은 MAC 계산에 필요한 시간을 기반으로 CBC 패딩에 대한 타이밍 공격을 시연했습니다. 이 공격을 방어하기 위해 구현에서는 패딩이 올바른지 여부에 관계없이 레코드 처리 시간이 본질적으로 동일하도록 보장해야 합니다. 일반적으로 이를 수행하는 가장 좋은 방법은 패딩이 잘못된 경우에도 MAC를 계산한 다음 패킷을 거부하는 것입니다. 예를 들어 패드가 잘못된 것으로 나타나면 구현에서는 길이가 0인 패드를 가정한 다음 MAC를 계산할 수 있습니다. MAC 성능은 데이터 조각의 크기에 어느 정도 좌우되기 때문에 작은 타이밍 채널이 남지만, 기존 MAC의 블록 크기가 크고 MAC의 크기가 작기 때문에 활용할 수 있을 만큼 크지는 않은 것으로 보입니다. 타이밍 신호.
---
##### **6.2.3.3. AEAD Ciphers**
AEAD \[AEAD\] 암호\(예: \[CCM\] 또는 \[GCM\]\)의 경우 AEAD 함수는 TLSCompressed.fragment 구조를 AEAD TLSCiphertext.fragment 구조와 변환합니다.
```text
struct {
opaque nonce_explicit[SecurityParameters.record_iv_length];
aead-ciphered struct {
opaque content[TLSCompressed.length];
};
} GenericAEADCipher;
```
AEAD 암호는 \[AEAD\]의 섹션 2.1에 설명된 대로 단일 키, nonce, 일반 텍스트 및 인증 확인에 포함될 "추가 데이터"를 입력으로 사용합니다. 키는 client\_write\_key 또는 server\_write\_key입니다. MAC 키는 사용되지 않습니다.
각 AEAD 암호 모음은 AEAD 작업에 제공된 nonce가 구성되는 방법과 GenericAEADCipher.nonce\_explicit 부분의 길이를 지정해야 합니다. 많은 경우에 그것은
\[AEAD\]의 섹션 3.2.1에 설명된 부분적으로 암시적인 nonce 기술을 사용하는 데 적합합니다. Record\_iv\_length는 명시적인 부분의 길이입니다. 이 경우 암시적 부분은 key\_block에서 client\_write\_iv 및 server\_write\_iv\(섹션 6.3에 설명됨\)로 파생되어야 하며 명시적 부분은 GenericAEAEDCipher.nonce\_explicit에 포함됩니다.
일반 텍스트는 TLSCompressed.fragment입니다.
추가\_데이터로 표시되는 추가 인증 데이터는 다음과 같이 정의됩니다.
```text
additional_data = seq_num + TLSCompressed.type +
TLSCompressed.version + TLSCompressed.length;
```
여기서 "+"는 연결을 나타냅니다.
aead\_output은 AEAD 암호화 작업에 의한 암호문 출력으로 구성됩니다. 길이는 일반적으로 TLSCompressed.length보다 크지만 AEAD 암호에 따라 그 양이 달라집니다. 암호에는 패딩이 포함될 수 있으므로 오버헤드의 양은 TLSCompressed.length 값에 따라 달라질 수 있습니다. 각 AEAD 암호는 1024바이트보다 큰 확장을 생성해서는 안 됩니다. 상징적으로,
```text
AEADEncrypted = AEAD-Encrypt(write_key, nonce, plaintext,
additional_data)
```
암호를 해독하고 확인하기 위해 암호는 키, nonce, "additional\_data" 및 AEADEncrypted 값을 입력으로 사용합니다. 출력은 일반 텍스트이거나 암호 해독이 실패했음을 나타내는 오류입니다. 별도의 무결성 검사는 없습니다. 그건:
```text
TLSCompressed.fragment = AEAD-Decrypt(write_key, nonce,
AEADEncrypted,
additional_data)
```
암호 해독에 실패하면 치명적인 bad\_record\_mac 경고가 생성되어야 합니다.
---
### **6.3. Key Calculation**
레코드 프로토콜에는 핸드셰이크 프로토콜에서 제공하는 보안 매개변수로부터 현재 연결 상태\(부록 A.6 참조\)에 필요한 키를 생성하는 알고리즘이 필요합니다.
마스터 비밀은 일련의 보안 바이트로 확장된 다음 클라이언트 쓰기 MAC 키, 서버 쓰기 MAC 키, 클라이언트 쓰기 암호화 키 및 서버 쓰기 암호화 키로 분할됩니다. 이들 각각은 해당 순서대로 바이트 시퀀스에서 생성됩니다. 사용되지 않은 값은 비어 있습니다. 일부 AEAD 암호에는 클라이언트 쓰기 IV와 서버 쓰기 IV가 추가로 필요할 수 있습니다\(섹션 6.2.3.3 참조\).
키와 MAC 키가 생성되면 마스터 비밀이 엔트로피 소스로 사용됩니다.
키 자료를 생성하려면 다음을 계산하세요.
```text
key_block = PRF(SecurityParameters.master_secret,
"key expansion",
SecurityParameters.server_random +
SecurityParameters.client_random);
```
충분한 출력이 생성될 때까지. 그런 다음 key\_block은 다음과 같이 분할됩니다.
```text
client_write_MAC_key[SecurityParameters.mac_key_length]
server_write_MAC_key[SecurityParameters.mac_key_length]
client_write_key[SecurityParameters.enc_key_length]
server_write_key[SecurityParameters.enc_key_length]
client_write_IV[SecurityParameters.fixed_iv_length]
server_write_IV[SecurityParameters.fixed_iv_length]
```
현재 client\_write\_IV 및 server\_write\_IV는 \[AEAD\]의 섹션 3.2.1에 설명된 암시적 nonce 기술에 대해서만 생성됩니다.
구현 참고 사항: 가장 많은 자료가 필요한 현재 정의된 암호 제품군은 AES\_256\_CBC\_SHA256입니다. 총 128바이트의 키 자료에는 2개의 32바이트 키와 2개의 32바이트 MAC 키가 필요합니다.
---
## **7. The TLS Handshaking Protocols**
TLS에는 피어가 레코드 계층에 대한 보안 매개변수에 동의하고, 자신을 인증하고, 협상된 보안 매개변수를 인스턴스화하고, 오류 조건을 서로 보고하도록 하는 데 사용되는 세 가지 하위 프로토콜이 있습니다.
핸드셰이크 프로토콜은 다음 항목으로 구성된 세션 협상을 담당합니다.
세션 식별자 - 활성 또는 재개 가능한 세션 상태를 식별하기 위해 서버에서 선택한 임의 바이트 시퀀스입니다.
피어 인증서 - 피어의 X509v3 \[PKIX\] 인증서입니다. 이 상태 요소는 null일 수 있습니다.
압축 방법 - 암호화 전에 데이터를 압축하는 데 사용되는 알고리즘입니다.
암호 사양 - 키 자료를 생성하는 데 사용되는 PRF\(의사 난수 함수\), 대량 데이터 암호화 알고리즘\(예: Null, AES 등\) 및 MAC 알고리즘\(예: HMAC-SHA1\)을 지정합니다. 또한 mac\_length와 같은 암호화 속성도 정의합니다. \(공식적인 정의는 부록 A.6을 참조하세요.\)
마스터 비밀 - 클라이언트와 서버 간에 공유되는 48바이트 비밀입니다.
재개 가능 - 세션을 사용하여 새 연결을 시작할 수 있는지 여부를 나타내는 플래그입니다.
그런 다음 이러한 항목은 애플리케이션 데이터를 보호할 때 레코드 계층에서 사용할 보안 매개변수를 생성하는 데 사용됩니다. TLS 핸드셰이크 프로토콜의 재개 기능을 통해 동일한 세션을 사용하여 많은 연결을 인스턴스화할 수 있습니다.
---
### **7.1. Change Cipher Spec Protocol**
암호화 사양 변경 프로토콜은 암호화 전략의 신호 전환을 위해 존재합니다. 프로토콜은 현재\(보류 중인 것이 아닌\) 연결 상태에서 암호화되고 압축되는 단일 메시지로 구성됩니다. 메시지는 값 1의 단일 바이트로 구성됩니다.
```text
struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;
```
ChangeCipherSpec 메시지는 클라이언트와 서버 모두에서 전송되어 후속 레코드가 새로 협상된 CipherSpec 및 키에 따라 보호될 것임을 수신자에게 알립니다. 이 메시지를 수신하면 수신자는 읽기 보류 상태를 읽기 현재 상태로 즉시 복사하도록 레코드 계층에 지시하게 됩니다. 이 메시지를 보낸 직후 발신자는 쓰기 보류 상태를 쓰기 활성 상태로 만들도록 레코드 계층에 지시해야 합니다.
\(섹션 6.1 참조\) ChangeCipherSpec 메시지는 보안 매개변수가 합의된 후 핸드셰이크 중에 전송되지만 확인하는 Finished 메시지가 전송되기 전에 전송됩니다.
참고: 연결에서 데이터가 흐르는 동안 재핸드셰이크가 발생하는 경우 통신 당사자는 이전 CipherSpec을 사용하여 계속 데이터를 보낼 수 있습니다. 그러나 ChangeCipherSpec이 전송되면 새 CipherSpec을 사용해야 합니다. ChangeCipherSpec을 보내는 첫 번째 측은 다른 쪽이 새로운 키 자료 계산을 완료했다는 사실을 알지 못합니다\(예: 시간이 많이 걸리는 공개 키 작업을 수행해야 하는 경우\). 따라서 수신자가 데이터를 버퍼링해야 하는 작은 시간 창이 존재할 수 있습니다. 실제로 현대 기계에서는 이 간격이 상당히 짧을 수 있습니다.
---
### **7.2. Alert Protocol**
TLS 레코드 레이어에서 지원하는 콘텐츠 유형 중 하나는 경고 유형입니다. 경고 메시지는 메시지의 심각도\(경고 또는 치명적\)와 경고에 대한 설명을 전달합니다. 치명적인 수준의 경고 메시지는 연결을 즉시 종료합니다. 이 경우 해당 세션에 해당하는 다른 연결은 계속될 수 있지만 세션 식별자를 무효화해야 하므로 실패한 세션이 새로운 연결을 설정하는 데 사용되는 것을 방지해야 합니다. 다른 메시지와 마찬가지로 경고 메시지도 현재 연결 상태에 따라 암호화되고 압축됩니다.
```text
enum { warning(1), fatal(2), (255) } AlertLevel;
enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110),
(255)
} AlertDescription;
struct {
AlertLevel level;
AlertDescription description;
} Alert;
```
---
#### **7.2.1. Closure Alerts**
클라이언트와 서버는 잘림 공격을 피하기 위해 연결이 종료되고 있다는 정보를 공유해야 합니다. 어느 쪽이든 종료 메시지 교환을 시작할 수 있습니다.
close\_notify - 이 메시지는 발신자가 이 연결에서 더 이상 메시지를 보내지 않을 것임을 수신자에게 알립니다. TLS 1.1부터는 연결을 제대로 닫지 못하는 경우 더 이상 세션을 재개하지 않아도 됩니다. 이는 광범위한 구현 관행을 따르기 위해 TLS 1.0에서 변경된 것입니다.
어느 쪽이든 close\_notify 경고를 보내 마감을 시작할 수 있습니다. 폐쇄 경고 이후 수신된 모든 데이터는 무시됩니다.
다른 치명적인 경고가 전송되지 않는 한, 각 당사자는 연결의 쓰기 측을 닫기 전에 close\_notify 경고를 보내야 합니다. 상대방은 반드시 자체적으로 close\_notify 경고로 응답하고 연결을 즉시 종료하고 보류 중인 쓰기를 삭제해야 합니다. 닫기 시작자가 연결의 읽기 측을 닫기 전에 응답하는 close\_notify 경고를 기다릴 필요는 없습니다.
TLS를 사용하는 애플리케이션 프로토콜이 TLS 연결이 닫힌 후 기본 전송을 통해 모든 데이터가 전달될 수 있도록 제공하는 경우 TLS 구현은 TLS 연결이 종료되었음을 애플리케이션 계층에 알리기 전에 응답하는 close\_notify 경고를 수신해야 합니다. 애플리케이션 프로토콜이 추가 데이터를 전송하지 않고 기본 전송 연결만 닫는 경우 구현은 응답 close\_notify를 기다리지 않고 전송을 닫도록 선택할 수 있습니다. 부품 없음
이 표준의 규정은 연결이 열리거나 닫힐 때를 포함하여 TLS에 대한 사용 프로필이 데이터 전송을 관리하는 방식을 지정해야 합니다.
참고: 연결을 닫으면 전송이 중단되기 전에 보류 중인 데이터가 안정적으로 전달된다고 가정합니다.
---
#### **7.2.2. Error Alerts**
TLS 핸드셰이크 프로토콜의 오류 처리는 매우 간단합니다. 오류가 감지되면 감지 당사자는 상대방에게 메시지를 보냅니다. 치명적인 경고 메시지를 전송하거나 수신하면 양측은 즉시 연결을 종료합니다. 서버와 클라이언트는 실패한 연결과 관련된 모든 세션 식별자, 키 및 비밀을 잊어야 합니다. 따라서 치명적인 경고로 종료된 연결은 재개되어서는 안 됩니다.
구현이 치명적인 경고로 정의된 조건을 만날 때마다 연결을 닫기 전에 적절한 경고를 보내야 합니다. 경고 수준이 명시적으로 지정되지 않은 모든 오류의 경우 전송 당사자는 이를 치명적인 오류로 처리할지 여부를 재량에 따라 결정할 수 있습니다. 구현이 경고를 보내기로 선택했지만 이후에 즉시 연결을 닫으려는 경우 치명적인 경고 수준에서 해당 경고를 보내야 합니다.
경고 수준의 알림이 전송 및 수신되면 일반적으로 연결이 정상적으로 계속될 수 있습니다. 수신측이 연결을 진행하지 않기로 결정한 경우\(예: 수락할 의사가 없다는 no\_renegotiation 경고를 받은 후\) 연결을 종료하기 위해 치명적인 경고를 보내야 합니다\(SHOULD\). 이를 감안할 때 일반적으로 보내는 당사자는 받는 당사자가 어떻게 행동할지 알 수 없습니다. 따라서 경고 알림은 송신측에서 연결을 계속하려는 경우 그다지 유용하지 않아 생략되는 경우도 있습니다. 예를 들어, 피어가 만료된 인증서를 수락하기로 결정하고\(아마도 사용자에게 이를 확인한 후\) 연결을 계속하려는 경우 일반적으로 인증서 만료 경고를 보내지 않습니다.
다음 오류 경고가 정의됩니다.
Unexpected\_message - 부적절한 메시지가 수신되었습니다. 이 경고는 항상 치명적이므로 적절한 구현 간의 통신에서 관찰되어서는 안 됩니다.
bad\_record\_mac - 잘못된 MAC로 레코드가 수신되면 이 경고가 반환됩니다. TLSCiphertext가 유효하지 않은 방식으로 해독되어 경고가 전송되는 경우에도 이 경고가 반환되어야 합니다. 즉, 블록 길이의 짝수가 아니었거나 확인 시 패딩 값이 올바르지 않았습니다. 이 메시지는 항상 치명적이며 적절한 구현 간의 통신에서 관찰되어서는 안 됩니다\(네트워크에서 메시지가 손상된 경우 제외\).
decryption\_failed\_RESERVED - 이 경고는 일부 이전 버전의 TLS에서 사용되었으며 CBC 모드\[CBCATT\]에 대한 특정 공격을 허용했을 수 있습니다. 호환 구현에 의해 전송되어서는 안 됩니다.
Record\_overflow - 길이가 2^14+2048바이트를 초과하는 TLSCiphertext 레코드가 수신되었거나 2^14+1024바이트를 초과하는 TLSCompressed 레코드로 암호 해독된 레코드가 수신되었습니다. 이 메시지는 항상 치명적이며 적절한 구현 간의 통신에서 관찰되어서는 안 됩니다\(네트워크에서 메시지가 손상된 경우 제외\).
decompression\_failure - 압축 해제 함수가 부적절한 입력\(예: 과도한 길이로 확장되는 데이터\)을 받았습니다. 이 메시지는 항상 치명적이므로 적절한 구현 간의 통신에서 관찰되어서는 안 됩니다.
handshake\_failure - handshake\_failure 경고 메시지의 수신은 발신자가 사용 가능한 옵션이 있는 경우 허용되는 보안 매개변수 집합을 협상할 수 없음을 나타냅니다. 이는 치명적인 오류입니다.
no\_certificate\_RESERVED - 이 경고는 SSLv3에서 사용되었지만 TLS의 어떤 버전에서도 사용되지 않았습니다. 호환 구현에 의해 전송되어서는 안 됩니다.
bad\_certificate - 인증서가 손상되었거나 올바르게 확인되지 않은 서명이 포함되어 있습니다.
unsupported\_certificate - 인증서가 지원되지 않는 유형이었습니다.
Certificate\_revoked - 서명자가 인증서를 취소했습니다.
Certificate\_expired - 인증서가 만료되었거나 현재 유효하지 않습니다.
Certificate\_unknown - 인증서를 처리하는 중에 다른\(지정되지 않은\) 문제가 발생하여 인증서를 사용할 수 없게 되었습니다.
불법\_파라미터 - 핸드셰이크의 필드가 범위를 벗어났거나 다른 필드와 일치하지 않습니다. 이 메시지는 항상 치명적입니다.
unknown\_ca - 유효한 인증서 체인 또는 부분 체인이 수신되었지만 CA 인증서를 찾을 수 없거나 알려진 신뢰할 수 있는 CA와 일치할 수 없기 때문에 인증서가 승인되지 않았습니다. 이 메시지는 항상 치명적입니다.
access\_denied - 유효한 인증서를 받았으나 접근 제어가 적용되었을 때 발신자가 협상을 진행하지 않기로 결정했습니다. 이 메시지는 항상 치명적입니다.
decode\_error - 일부 필드가 지정된 범위를 벗어났거나 메시지 길이가 올바르지 않아 메시지를 디코딩할 수 없습니다. 이 메시지는 항상 치명적이며 적절한 구현 간의 통신에서 관찰되어서는 안 됩니다\(네트워크에서 메시지가 손상된 경우 제외\).
decrypt\_error - 서명을 올바르게 확인하거나 완료됨 메시지를 확인할 수 없는 것을 포함하여 핸드셰이크 암호화 작업이 실패했습니다. 이 메시지는 항상 치명적입니다.
내보내기\_restriction\_RESERVED - 이 경고는 일부 이전 버전의 TLS에서 사용되었습니다. 호환 구현에 의해 전송되어서는 안 됩니다.
프로토콜\_버전 - 클라이언트가 협상을 시도한 프로토콜 버전이 인식되지만 지원되지 않습니다. \(예를 들어 보안상의 이유로 이전 프로토콜 버전은 사용하지 않을 수 있습니다.\) 이 메시지는 항상 치명적입니다.
불충분한\_보안 - 서버가 클라이언트에서 지원하는 것보다 더 안전한 암호를 요구하기 때문에 특히 협상이 실패한 경우 handshake\_failure 대신 반환됩니다. 이 메시지는 항상 치명적입니다.
Internal\_error - 피어와 관련되지 않은 내부 오류 또는 프로토콜의 정확성\(예: 메모리 할당 실패\)으로 인해 계속할 수 없습니다. 이 메시지는 항상 치명적입니다.
user\_canceled - 이 핸드셰이크는 프로토콜 오류와 무관한 어떤 이유로 취소되고 있습니다. 핸드셰이크가 완료된 후 사용자가 작업을 취소하는 경우 close\_notify를 전송하여 연결을 닫는 것이 더 적절합니다. 이 경고 뒤에는 close\_notify가 와야 합니다. 이 메시지는 일반적으로 경고입니다.
no\_renegotiation - hello 요청에 대한 응답으로 클라이언트가 전송하거나 초기 핸드셰이크 이후 클라이언트 hello에 대한 응답으로 서버가 전송합니다. 둘 중 하나는 일반적으로 재협상으로 이어집니다. 그것이 적절하지 않은 경우 수신자는 이 경고로 응답해야 합니다. 이 시점에서 원래 요청자는 연결을 계속할지 여부를 결정할 수 있습니다. 이것이 적절한 경우 중 하나는 서버가 요청을 충족하기 위해 프로세스를 생성한 경우입니다. 프로세스는 시작 시 보안 매개변수\(키 길이, 인증 등\)를 수신할 수 있으며, 그 이후에는 이러한 매개변수에 대한 변경 사항을 전달하기 어려울 수 있습니다. 이 메시지는 항상 경고입니다.
unsupported\_extension - 해당 클라이언트 hello에 넣지 않은 확장이 포함된 확장 서버 hello를 수신하는 클라이언트가 보냅니다. 이 메시지는 항상 치명적입니다.
새로운 경고 값은 섹션 12에 설명된 대로 IANA에 의해 할당됩니다.
---
### **7.3. Handshake Protocol Overview**
세션 상태의 암호화 매개변수는 TLS 레코드 계층 위에서 작동하는 TLS 핸드셰이크 프로토콜에 의해 생성됩니다. TLS 클라이언트와 서버가 처음 통신을 시작하면 프로토콜 버전에 동의하고, 암호화 알고리즘을 선택하고, 선택적으로 서로 인증하고, 공개 키 암호화 기술을 사용하여 공유 비밀을 생성합니다.
TLS 핸드셰이크 프로토콜에는 다음 단계가 포함됩니다.
- 알고리즘에 동의하고, 임의의 값을 교환하고, 세션 재개를 확인하기 위해 인사 메시지를 교환합니다.
- 클라이언트와 서버가 프리마스터 비밀에 동의할 수 있도록 필요한 암호화 매개변수를 교환합니다.
- 클라이언트와 서버가 스스로 인증할 수 있도록 인증서와 암호화 정보를 교환합니다.
- 프리마스터 시크릿에서 마스터 시크릿을 생성하고 임의의 값을 교환합니다.
- 레코드 레이어에 보안 매개변수를 제공합니다.
- 클라이언트와 서버가 피어가 동일한 보안 매개변수를 계산했는지, 공격자에 의한 변조 없이 핸드셰이크가 발생했는지 확인할 수 있도록 허용합니다.
상위 계층은 TLS가 항상 두 피어 간의 가능한 가장 강력한 연결을 협상하는지 여부에 지나치게 의존해서는 안 됩니다. 중간자 공격자가 두 엔터티를 그들이 지원하는 가장 덜 안전한 방법으로 떨어뜨리도록 시도할 수 있는 방법에는 여러 가지가 있습니다. 프로토콜은 이러한 위험을 최소화하도록 설계되었지만 여전히 가능한 공격이 있습니다. 예를 들어 공격자는 보안 서비스가 실행되는 포트에 대한 액세스를 차단하거나 피어가 인증되지 않은 연결을 협상하도록 시도할 수 있습니다. 기본 규칙은 더 높은 수준이 보안 요구 사항을 인식해야 하며 필요한 것보다 덜 안전한 채널을 통해 정보를 전송하지 않는다는 것입니다. TLS 프로토콜은 모든 암호 제품군이 약속된 보안 수준을 제공한다는 점에서 안전합니다. 인증서를 확인한 호스트와 1024비트 RSA 키 교환을 통해 3DES를 협상하면 그만큼 안전할 것으로 기대할 수 있습니다.
이러한 목표는 다음과 같이 요약할 수 있는 핸드셰이크 프로토콜에 의해 달성됩니다. 클라이언트는 서버가 ServerHello 메시지로 응답해야 하는 ClientHello 메시지를 보냅니다. 그렇지 않으면 치명적인 오류가 발생하고 연결이 실패합니다. ClientHello 및 ServerHello는 클라이언트와 서버 간의 보안 강화 기능을 설정하는 데 사용됩니다. ClientHello 및 ServerHello는 프로토콜 버전, 세션 ID, 암호화 제품군 및 압축 방법과 같은 속성을 설정합니다. 또한 두 개의 임의 값\(ClientHello.random 및 ServerHello.random\)이 생성되고 교환됩니다.
실제 키 교환에서는 서버 인증서, ServerKeyExchange, 클라이언트 인증서, ClientKeyExchange 등 최대 4개의 메시지를 사용합니다. 이러한 메시지의 형식을 지정하고 클라이언트와 서버가 공유 비밀에 동의할 수 있도록 메시지 사용을 정의하여 새로운 키 교환 방법을 만들 수 있습니다. 이 비밀은 꽤 길어야 합니다. 현재 정의된 키 교환 방법은 46바이트 이상의 비밀을 교환합니다.
hello 메시지에 이어 서버는 인증을 받아야 하는 경우 인증서 메시지에 인증서를 보냅니다. 또한 필요한 경우\(예: 서버에 인증서가 없거나 해당 인증서가 서명 전용인 경우\) ServerKeyExchange 메시지가 전송될 수 있습니다. 서버가 인증되면 선택한 암호 제품군에 적합한 경우 클라이언트로부터 인증서를 요청할 수 있습니다. 다음으로 서버는 핸드셰이크의 hello-message 단계가 완료되었음을 나타내는 ServerHelloDone 메시지를 보냅니다. 그러면 서버는 클라이언트 응답을 기다립니다. 서버가 CertificateRequest 메시지를 보낸 경우 클라이언트는 반드시 인증서 메시지를 보내야 합니다. 이제 ClientKeyExchange 메시지가 전송되고 해당 메시지의 내용은 ClientHello와 ServerHello 사이에서 선택된 공개 키 알고리즘에 따라 달라집니다. 클라이언트가 서명 기능이 있는 인증서를 보낸 경우 디지털 서명된 CertificateVerify 메시지가 인증서에 있는 개인 키의 소유를 명시적으로 확인하기 위해 전송됩니다.
이 시점에서 클라이언트는 ChangeCipherSpec 메시지를 전송하고 클라이언트는 보류 중인 Cipher Spec을 현재 Cipher Spec에 복사합니다. 그런 다음 클라이언트는 즉시 새 알고리즘, 키 및 비밀에 따라 Finished 메시지를 보냅니다. 이에 대한 응답으로 서버는 자체 ChangeCipherSpec 메시지를 보내고 보류 중인 내용을 현재 Cipher Spec으로 전송한 다음 새 Cipher Spec에 따라 Finished 메시지를 보냅니다. 이 시점에서 핸드셰이크가 완료되고 클라이언트와 서버는 애플리케이션 계층 데이터 교환을 시작할 수 있습니다. \(아래 흐름도를 참조하십시오.\) 애플리케이션 데이터는 첫 번째 핸드셰이크가 완료되기 전\(TLS\_NULL\_WITH\_NULL\_NULL 이외의 암호화 제품군이 설정되기 전\)에 전송되어서는 안 됩니다.
```text
Client Server
ClientHello -------->
ServerHello
Certificate*
ServerKeyExchange*
CertificateRequest*
<-------- ServerHelloDone
Certificate*
ClientKeyExchange
CertificateVerify*
[ChangeCipherSpec]
Finished -------->
[ChangeCipherSpec]
<-------- Finished
Application Data <-------> Application Data
Figure 1. Message flow for a full handshake
```
\* 항상 전송되지 않는 선택적 메시지 또는 상황에 따른 메시지를 나타냅니다.
참고: 파이프라인 중단을 방지하기 위해 ChangeCipherSpec은 독립적인 TLS 프로토콜 콘텐츠 유형이며 실제로는 TLS 핸드셰이크 메시지가 아닙니다.
클라이언트와 서버가 이전 세션을 재개하거나 기존 세션을 복제하기로 결정한 경우\(새 보안 매개변수를 협상하는 대신\) 메시지 흐름은 다음과 같습니다.
클라이언트는 재개할 세션의 세션 ID를 사용하여 ClientHello를 보냅니다. 그런 다음 서버는 세션 캐시에서 일치하는 항목을 확인합니다. 일치하는 항목이 발견되고 서버가 지정된 세션 상태에서 연결을 다시 설정하려는 경우 동일한 세션 ID 값을 사용하여 ServerHello를 보냅니다. 이 시점에서 클라이언트와 서버는 모두 ChangeCipherSpec 메시지를 보내고 바로 Finished 메시지로 진행해야 합니다. 재설정이 완료되면 클라이언트와 서버는 애플리케이션 계층 데이터 교환을 시작할 수 있습니다. \(아래 순서도를 참조하세요.\) 일치하는 세션 ID가 없으면 서버는 새 세션 ID를 생성하고 TLS 클라이언트와 서버는 전체 핸드셰이크를 수행합니다.
```text
Client Server
ClientHello -------->
ServerHello
[ChangeCipherSpec]
<-------- Finished
[ChangeCipherSpec]
Finished -------->
Application Data <-------> Application Data
Figure 2. Message flow for an abbreviated handshake
```
각 메시지의 내용과 의미는 다음 섹션에서 자세히 설명됩니다.
---
### **7.4. Handshake Protocol**
TLS 핸드셰이크 프로토콜은 TLS 레코드 프로토콜의 정의된 상위 수준 클라이언트 중 하나입니다. 이 프로토콜은 세션의 보안 속성을 협상하는 데 사용됩니다. 핸드셰이크 메시지는 TLS 레코드 계층에 제공되며, 여기서 메시지는 하나 이상의 TLSPlaintext 구조 내에 캡슐화되어 현재 활성 세션 상태에 지정된 대로 처리 및 전송됩니다.
```text
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20), (255)
} HandshakeType;
struct {
HandshakeType msg_type; /* handshake type */
uint24 length; /* bytes in message */
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;
```
핸드셰이크 프로토콜 메시지는 전송되어야 하는 순서대로 아래에 표시됩니다. 예상치 못한 순서로 핸드셰이크 메시지를 보내면 치명적인 오류가 발생합니다. 그러나 불필요한 핸드셰이크 메시지는 생략할 수 있습니다. 순서에 대한 한 가지 예외에 유의하십시오. 인증서 메시지는 핸드셰이크\(서버에서 클라이언트로, 그 다음 클라이언트에서 서버로\)에서 두 번 사용되지만 첫 번째 위치에서만 설명됩니다. 이러한 순서 규칙에 구속되지 않는 메시지 중 하나는 HelloRequest 메시지입니다. 이 메시지는 언제든지 보낼 수 있지만 핸드셰이크 도중에 도착하면 클라이언트에서 이를 무시해야 합니다.
새로운 핸드셰이크 메시지 유형은 섹션 12에 설명된 대로 IANA에 의해 할당됩니다.
---
#### **7.4.1. Hello Messages**
Hello 단계 메시지는 클라이언트와 서버 간에 보안 강화 기능을 교환하는 데 사용됩니다. 새 세션이 시작되면 레코드 계층의 연결 상태 암호화, 해시 및 압축 알고리즘이 null로 초기화됩니다. 현재 연결 상태는 재협상 메시지에 사용됩니다.
---
##### **7.4.1.1. Hello Request**
이 메시지가 전송되는 시기:
- HelloRequest 메시지는 언제든지 서버에 의해 전송될 수 있습니다.
이 메시지의 의미:
- HelloRequest는 클라이언트가 협상 프로세스를 새로 시작해야 한다는 간단한 알림입니다. 이에 대한 응답으로 클라이언트는 편리한 경우 ClientHello 메시지를 보내야 합니다. 이 메시지는 어느 쪽이 클라이언트인지 서버인지 확인하기 위한 것이 아니라 단지 새로운 협상을 시작하기 위한 것입니다. 서버는 클라이언트의 초기 연결 시 즉시 HelloRequest를 보내서는 안 됩니다. 이때 ClientHello를 보내는 것은 클라이언트의 작업입니다.
- 클라이언트가 현재 세션을 협상 중인 경우 이 메시지는 클라이언트에서 무시됩니다. 세션 재협상을 원하지 않는 경우 클라이언트는 이 메시지를 무시할 수 있으며, 클라이언트가 원하는 경우 no\_renegotiation 경고로 응답할 수 있습니다. 핸드셰이크 메시지는 애플리케이션 데이터보다 전송 우선순위를 가지도록 되어 있으므로 클라이언트로부터 몇 개의 레코드만 수신되기 전에 협상이 시작될 것으로 예상됩니다. 서버가 HelloRequest를 보냈지만 응답으로 ClientHello를 받지 못한 경우 치명적인 경고와 함께 연결이 종료될 수 있습니다.
- HelloRequest를 보낸 후 서버는 후속 핸드셰이크 협상이 완료될 때까지 요청을 반복해서는 안 됩니다.
이 메시지의 구조:
```text
struct { } HelloRequest;
```
이 메시지는 핸드셰이크 전반에 걸쳐 유지되고 완료 메시지와 인증서 확인 메시지에 사용되는 메시지 해시에 포함되어서는 안 됩니다.
---
##### **7.4.1.2. Client Hello**
이 메시지가 전송되는 시기:
- 클라이언트가 서버에 처음 연결되면 첫 번째 메시지로 ClientHello를 보내야 합니다. 클라이언트는 기존 연결의 보안 매개변수를 재협상하기 위해 HelloRequest에 대한 응답으로 또는 자체 주도로 ClientHello를 보낼 수도 있습니다.
이 메시지의 구조:
- ClientHello 메시지에는 나중에 프로토콜에서 사용되는 임의의 구조가 포함되어 있습니다.
```text
struct {
uint32 gmt_unix_time;
opaque random_bytes[28];
} Random;
```
- gmt\_unix\_time 발신자의 내부 시계에 따른 표준 UNIX 32비트 형식\(UTC, 1970년 1월 1일 자정 이후의 초, 윤초 무시\)의 현재 시간 및 날짜입니다. 기본 TLS 프로토콜에서는 시계를 올바르게 설정할 필요가 없습니다. 더 높은 수준 또는 응용 프로그램 프로토콜은 추가 요구 사항을 정의할 수 있습니다. 역사적인 이유로 데이터 요소의 이름은 현재 전세계 시간 기준인 UTC의 전신인 GMT를 사용하여 명명되었습니다.
- 보안 난수 생성기에 의해 생성된 random\_bytes 28바이트.
ClientHello 메시지에는 가변 길이 세션 식별자가 포함됩니다. 비어 있지 않은 경우 값은 클라이언트가 재사용하려는 보안 매개변수가 있는 동일한 클라이언트와 서버 간의 세션을 식별합니다. 세션 식별자는 이전 연결에서 나올 수 있습니다.
이 연결 또는 현재 활성화된 다른 연결에서. 두 번째 옵션은 클라이언트가 연결의 무작위 구조와 파생 값만 업데이트하려는 경우에 유용하며, 세 번째 옵션을 사용하면 전체 핸드셰이크 프로토콜을 반복하지 않고도 여러 개의 독립적인 보안 연결을 설정할 수 있습니다. 이러한 독립적인 연결은 순차적으로 또는 동시에 발생할 수 있습니다. SessionID는 협상하는 핸드셰이크가 완료됨 메시지 교환으로 완료되고 노화로 인해 제거되거나 세션과 관련된 연결에서 치명적인 오류가 발생하여 제거될 때까지 지속되면 유효해집니다. SessionID의 실제 내용은 서버에 의해 정의됩니다.
```text
opaque SessionID<0..32>;
```
경고: SessionID는 암호화 또는 즉각적인 MAC 보호 없이 전송되므로 서버는 세션 식별자에 기밀 정보를 배치하거나 가짜 세션 식별자의 내용으로 인해 보안 위반이 발생하도록 해서는 안 됩니다. \(SessionID를 포함하여 전체적으로 핸드셰이크의 내용은 핸드셰이크가 끝날 때 교환되는 완료 메시지에 의해 보호됩니다.\)
ClientHello 메시지를 통해 클라이언트에서 서버로 전달되는 암호화 제품군 목록에는 클라이언트가 선호하는 순서\(선호하는 항목부터\)에 따라 클라이언트가 지원하는 암호화 알고리즘의 조합이 포함되어 있습니다. 각 암호화 제품군은 키 교환 알고리즘, 대량 암호화 알고리즘\(비밀 키 길이 포함\), MAC 알고리즘 및 PRF를 정의합니다. 서버는 암호 제품군을 선택하거나, 허용 가능한 선택 사항이 없으면 핸드셰이크 실패 경고를 반환하고 연결을 닫습니다. 목록에 서버가 인식하지 않거나 지원하지 않거나 사용하기를 원하는 암호 그룹이 포함된 경우 서버는 해당 암호 그룹을 무시하고 나머지 암호 그룹을 평소대로 처리해야 합니다.
```text
uint8 CipherSuite[2]; /* Cryptographic suite selector */
```
ClientHello에는 클라이언트가 지원하는 압축 알고리즘 목록이 포함되어 있으며 클라이언트의 기본 설정에 따라 정렬됩니다.
```text
enum { null(0), (255) } CompressionMethod;
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ClientHello;
```
TLS를 사용하면 확장이 확장 블록의 압축\_메소드 필드를 따를 수 있습니다. 확장의 존재는 ClientHello의 끝에서 압축 방법 뒤에 바이트가 있는지 여부를 확인하여 감지할 수 있습니다. 선택적 데이터를 감지하는 이 방법은 가변 길이 필드를 갖는 일반적인 TLS 방법과 다르지만 확장이 정의되기 전에 TLS와의 호환성을 위해 사용됩니다.
client\_version - 클라이언트가 이 세션 동안 통신하기를 원하는 TLS 프로토콜의 버전입니다. 이는 클라이언트가 지원하는 최신\(가장 높은 값\) 버전이어야 합니다. 이 사양 버전의 경우 버전은 3.3입니다\(이전 버전과의 호환성에 대한 자세한 내용은 부록 E 참조\).
무작위 - 클라이언트가 생성한 무작위 구조입니다.
session\_id - 클라이언트가 이 연결에 사용하려는 세션의 ID입니다. session\_id를 사용할 수 없거나 클라이언트가 새 보안 매개변수를 생성하려는 경우 이 필드는 비어 있습니다.
cipher\_suites - 클라이언트가 지원하는 암호화 옵션 목록이며 클라이언트의 첫 번째 기본 설정이 먼저입니다. session\_id 필드가 비어 있지 않은 경우\(세션 재개 요청 암시\), 이 벡터는 최소한 해당 세션의 cipher\_suite를 포함해야 합니다. 값은 부록 A.5에 정의되어 있습니다.
압축\_방법 - 클라이언트가 지원하는 압축 방법 목록이며 클라이언트 기본 설정에 따라 정렬됩니다. session\_id 필드가 비어 있지 않은 경우\(세션 재개 요청 암시\), 다음을 포함해야 합니다.
- 해당 세션의 압축 방법. 이 벡터는 CompressionMethod.null을 포함해야 하며 모든 구현은 지원해야 합니다. 따라서 클라이언트와 서버는 항상 압축 방법에 동의할 수 있습니다.
확장 - 클라이언트는 확장 필드에 데이터를 전송하여 서버에서 확장 기능을 요청할 수 있습니다. 실제 "확장" 형식은 섹션 7.4.1.4에 정의되어 있습니다.
클라이언트가 확장을 사용하여 추가 기능을 요청하고 서버에서 이 기능을 제공하지 않는 경우 클라이언트는 핸드셰이크를 중단할 수 있습니다. 서버는 확장 필드가 있거나 없는 ClientHello 메시지를 수락해야 하며\(다른 모든 메시지의 경우에도\) 메시지의 데이터 양이 이러한 형식 중 하나와 정확하게 일치하는지 확인해야 합니다. 그렇지 않은 경우 치명적인 "decode\_error" 경고를 보내야 합니다.
ClientHello 메시지를 보낸 후 클라이언트는 ServerHello 메시지를 기다립니다. HelloRequest를 제외하고 서버에서 반환된 모든 핸드셰이크 메시지는 치명적인 오류로 처리됩니다.
---
##### **7.4.1.3. Server Hello**
이 메시지가 전송되는 시기:
- 서버는 허용 가능한 알고리즘 세트를 찾을 수 있을 때 ClientHello 메시지에 대한 응답으로 이 메시지를 보냅니다. 일치하는 항목을 찾을 수 없으면 핸드셰이크 실패 경고로 응답합니다.
이 메시지의 구조:
```text
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ServerHello;
```
확장 기능의 존재는 ServerHello 끝에 있는 압축 방법 필드 뒤에 바이트가 있는지 여부를 확인하여 감지할 수 있습니다.
server\_version - 이 필드에는 클라이언트 hello에서 클라이언트가 제안한 것 중 낮은 값과 서버에서 지원하는 가장 높은 값이 포함됩니다. 이 사양 버전의 경우 버전은 3.3입니다. \(이전 버전과의 호환성에 대한 자세한 내용은 부록 E를 참조하세요.\)
무작위 - 이 구조는 서버에 의해 생성되며 ClientHello.random에서 독립적으로 생성되어야 합니다.
session\_id - 이 연결에 해당하는 세션의 ID입니다. ClientHello.session\_id가 비어 있지 않은 경우 서버는 세션 캐시에서 일치하는 항목을 찾습니다. 일치하는 항목이 발견되고 서버가 지정된 세션 상태를 사용하여 새 연결을 설정하려는 경우 서버는 클라이언트가 제공한 것과 동일한 값으로 응답합니다. 이는 재개된 세션을 나타내며 당사자가 완료 메시지로 직접 진행해야 함을 나타냅니다. 그렇지 않으면 이 필드에는 새 세션을 식별하는 다른 값이 포함됩니다. 서버는 세션이 캐시되지 않아 재개될 수 없음을 나타내기 위해 빈 session\_id를 반환할 수 있습니다. 세션이 재개되면 원래 협상했던 것과 동일한 암호화 제품군을 사용하여 재개되어야 합니다. 이전에 session\_id를 제공했더라도 서버가 세션을 재개해야 한다는 요구 사항은 없습니다. 클라이언트는 핸드셰이크 중에 새로운 암호 제품군 협상을 포함하여 전체 협상을 수행할 준비가 되어 있어야 합니다.
cipher\_suite - ClientHello.cipher\_suites의 목록에서 서버가 선택한 단일 암호 제품군입니다. 재개된 세션의 경우 이 필드는 재개되는 세션 상태의 값입니다.
압축\_방법 - ClientHello.compression\_methods의 목록에서 서버가 선택한 단일 압축 알고리즘입니다. 재개된 세션의 경우 이 필드는 재개된 세션 상태의 값입니다.
확장 - 확장 목록입니다. 클라이언트가 제공하는 확장만 서버 목록에 나타날 수 있습니다.
---
##### **7.4.1.4. Hello Extensions**
확장 형식은 다음과 같습니다.
```text
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
enum {
signature_algorithms(13), (65535)
} ExtensionType;
Here:
```
- "extension\_type"은 특정 확장 유형을 식별합니다.
- "extension\_data"에는 특정 확장 유형과 관련된 정보가 포함됩니다.
초기 확장 세트는 동반 문서 \[TLSEXT\]에 정의되어 있습니다. 확장 유형 목록은 섹션 12에 설명된 대로 IANA에서 관리합니다.
해당 ClientHello에 동일한 확장 유형이 표시되지 않는 한 확장 유형은 ServerHello에 표시되어서는 안 됩니다. 클라이언트가 연결된 ClientHello에서 요청하지 않은 확장 유형을 ServerHello에서 수신하는 경우 unsupported\_extension fatal 경고와 함께 핸드셰이크를 중단해야 합니다.
그럼에도 불구하고 향후 이 프레임워크 내에서 "서버 지향" 확장이 제공될 수 있습니다. 이러한 확장\(예: x 유형\)은 클라이언트가 확장 유형을 지원함을 나타내기 위해 먼저 빈 Extension\_data를 사용하여 ClientHello에서 x 유형의 확장을 보내야 합니다. 이 경우 클라이언트는 확장 유형을 이해할 수 있는 기능을 제공하고 서버는 클라이언트의 제안을 받아들입니다.
ClientHello 또는 ServerHello 메시지에 다양한 유형의 여러 확장이 있는 경우 확장은 어떤 순서로든 나타날 수 있습니다. 동일한 유형의 확장이 두 개 이상 있어서는 안 됩니다.
마지막으로, 새 세션을 시작할 때와 세션 재개를 요청할 때 모두 연장이 전송될 수 있습니다. 실제로 세션 재개를 요청하는 클라이언트는 일반적으로 서버가 이 요청을 수락할지 여부를 알지 못하므로 재개를 시도하지 않을 경우 보낼 것과 동일한 확장을 보내야 합니다.
일반적으로 각 확장 유형의 사양은 전체 핸드셰이크와 세션 재개 중 확장의 효과를 설명해야 합니다. 대부분의 최신 TLS 확장은 세션이 시작될 때만 관련됩니다. 이전 세션이 재개되면 서버는 클라이언트 Hello에서 이러한 확장을 처리하지 않으며 이를 Server Hello에 포함하지 않습니다. 그러나 일부 확장은 세션 재개 중에 다른 동작을 지정할 수 있습니다.
이 프로토콜에서는 새로운 기능과 기존 기능 사이에 미묘한\(그리 미묘하지는 않은\) 상호 작용이 발생할 수 있으며 이로 인해 전체 보안이 크게 저하될 수 있습니다. 새로운 확장을 디자인할 때 다음 사항을 고려해야 합니다.
- 서버가 확장에 동의하지 않는 경우는 오류 조건이고, 일부는 단순히 특정 기능 지원을 거부하는 경우입니다. 일반적으로 전자에는 오류 경고를 사용해야 하고 후자에는 서버 확장 응답의 필드를 사용해야 합니다.
- 확장은 가능한 한 핸드셰이크 메시지를 조작하여 특정 기능을 강제로 사용\(또는 사용하지 않음\)하는 공격을 방지하도록 설계되어야 합니다. 해당 기능이 보안 문제를 일으키는 것으로 판단되는지 여부에 관계없이 이 원칙을 따라야 합니다.
- 확장 필드가 완료된 메시지 해시에 대한 입력에 포함되어 있다는 사실만으로도 충분하지만 확장이 핸드셰이크 단계에서 전송된 메시지의 의미를 변경할 때는 극도의 주의가 필요합니다. 설계자와 구현자는 핸드셰이크가 인증될 때까지 적극적인 공격자가 메시지를 수정하고 확장을 삽입, 제거 또는 교체할 수 있다는 사실을 알고 있어야 합니다.
- TLS 설계의 주요 측면을 변경하기 위해 확장을 사용하는 것이 기술적으로 가능합니다. 예를 들어 암호 제품군 협상 설계 등이 있습니다. 이는 권장되지 않습니다. 새로운 버전의 TLS를 정의하는 것이 더 적절할 것입니다. 특히 TLS 핸드셰이크 알고리즘에는 버전 번호를 기반으로 버전 롤백 공격에 대한 특정 보호 기능이 있고 버전 롤백 가능성은 모든 주요 설계 변경에서 중요한 고려 사항이어야 하기 때문입니다.
---
###### **7.4.1.4.1. Signature Algorithms**
클라이언트는 "signature\_algorithms" 확장을 사용하여 어떤 서명/해시 알고리즘 쌍이 디지털 서명에 사용될 수 있는지 서버에 나타냅니다. 이 확장의 "extension\_data" 필드에는 "supported\_signature\_algorithms" 값이 포함되어 있습니다.
```text
enum {
none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
sha512(6), (255)
} HashAlgorithm;
enum { anonymous(0), rsa(1), dsa(2), ecdsa(3), (255) }
SignatureAlgorithm;
struct {
HashAlgorithm hash;
SignatureAlgorithm signature;
} SignatureAndHashAlgorithm;
SignatureAndHashAlgorithm
supported_signature_algorithms<2..2^16-2>;
```
각 SignatureAndHashAlgorithm 값은 클라이언트가 확인하려는 단일 해시/서명 쌍을 나열합니다. 값은 선호도가 높은 순서대로 표시됩니다.
참고: 모든 서명 알고리즘과 해시 알고리즘이 구현에 의해 허용되는 것은 아니기 때문에\(예: SHA-1을 사용하는 DSA\(SHA-256은 제외\)\) 여기에 알고리즘은 쌍으로 나열됩니다.
hash - 이 필드는 사용될 수 있는 해시 알고리즘을 나타냅니다. 값은 각각 해시되지 않은 데이터인 MD5 \[MD5\], SHA-1, SHA-224, SHA-256, SHA-384 및 SHA-512 \[SHS\]에 대한 지원을 나타냅니다. 서명 전 해싱이 필요하지 않은 서명 알고리즘의 경우 향후 확장성을 위해 "none" 값이 제공됩니다.
서명 - 이 필드는 사용될 수 있는 서명 알고리즘을 나타냅니다. 값은 각각 RSASSA-PKCS1-v1\_5 \[PKCS1\] 및 DSA \[DSS\] 및 ECDSA \[ECDSA\]라는 익명 서명을 나타냅니다. "익명" 값은 이 문맥에서는 의미가 없지만 섹션 7.4.3에서는 사용됩니다. 이 확장 프로그램에는 표시되어서는 안 됩니다.
이 확장의 의미는 암호화 제품군이 허용되는 서명 알고리즘을 나타내지만 해시 알고리즘은 나타내지 않기 때문에 다소 복잡합니다. 섹션 7.4.2 및 7.4.3에서는 적절한 규칙을 설명합니다.
클라이언트가 기본 해시 및 서명 알고리즘\(이 섹션에 나열됨\)만 지원하는 경우 서명\_알고리즘 확장을 생략할 수 있습니다. 클라이언트가 기본 알고리즘을 지원하지 않거나 다른 해시 및 서명 알고리즘을 지원하는 경우\(그리고 서버에서 보낸 메시지를 확인하는 데 이를 사용하려는 경우\(예: 서버 인증서 및 서버 키 교환\)\) 반드시 다음을 보내야 합니다.
서명\_알고리즘 확장, 허용할 알고리즘을 나열합니다.
클라이언트가 서명\_알고리즘 확장을 보내지 않으면 서버는 다음을 수행해야 합니다.
- 협상된 키 교환 알고리즘이 \(RSA, DHE\_RSA, DH\_RSA, RSA\_PSK, ECDH\_RSA, ECDHE\_RSA\) 중 하나인 경우 클라이언트가 {sha1,rsa} 값을 보낸 것처럼 동작합니다.
- 협상된 키 교환 알고리즘이 \(DHE\_DSS, DH\_DSS\) 중 하나인 경우 클라이언트가 {sha1,dsa} 값을 보낸 것처럼 동작합니다.
- 협상된 키 교환 알고리즘이 \(ECDH\_ECDSA, ECDHE\_ECDSA\) 중 하나인 경우 클라이언트가 {sha1,ecdsa} 값을 보낸 것처럼 동작합니다.
참고: 이는 명시적인 규칙이 없는 TLS 1.1의 변경 사항이지만 실제로는 피어가 MD5 및 SHA-1을 지원한다고 가정할 수 있습니다.
참고: 이 확장은 TLS 1.2 이전 버전에서는 의미가 없습니다. 클라이언트가 이전 버전을 제공하는 경우 이를 제공해서는 안 됩니다. 그러나 클라이언트가 이를 제공하더라도 \[TLSEXT\]에 지정된 규칙은 서버가 이해하지 못하는 확장을 무시하도록 요구합니다.
서버는 이 확장을 보내면 안 됩니다. TLS 서버는 이 확장 수신을 지원해야 합니다.
세션 재개를 수행할 때 이 확장은 Server Hello에 포함되지 않으며 서버는 Client Hello\(있는 경우\)의 확장을 무시합니다.
---
#### **7.4.2. Server Certificate**
이 메시지가 전송되는 시기:
- 서버는 합의된 키 교환 방법이 인증을 위해 인증서를 사용할 때마다 인증서 메시지를 보내야 합니다\(여기에는 DH\_anon을 제외하고 이 문서에 정의된 모든 키 교환 방법이 포함됩니다\). 이 메시지는 항상 ServerHello 메시지 바로 뒤에 표시됩니다.
이 메시지의 의미:
- 이 메시지는 서버의 인증서 체인을 클라이언트에 전달합니다.
- 인증서는 협상된 암호 제품군의 키 교환 알고리즘 및 협상된 확장에 적합해야 합니다.
이 메시지의 구조:
```text
opaque ASN.1Cert<1..2^24-1>;
struct {
ASN.1Cert certificate_list<0..2^24-1>;
} Certificate;
```
Certificate\_list - 인증서의 시퀀스\(체인\)입니다. 보낸 사람의 인증서가 목록에서 가장 먼저 나와야 합니다. 다음의 각 인증서는 이전 인증서를 직접 인증해야 합니다. 인증서 유효성 검사에는 루트 키가 독립적으로 배포되어야 하기 때문에 루트 인증 기관을 지정하는 자체 서명된 인증서는 어떤 경우에도 이를 검증하기 위해 원격 측이 이미 인증서를 소유하고 있어야 한다는 가정 하에 체인에서 생략될 수 있습니다.
인증서 요청 메시지에 대한 클라이언트의 응답에는 동일한 메시지 유형과 구조가 사용됩니다. 클라이언트는 서버의 인증 요청에 대한 응답으로 보낼 적절한 인증서가 없는 경우 인증서를 보내지 않을 수 있습니다.
참고: PKCS #6 \[PKCS6\] 확장 인증서가 사용되지 않기 때문에 PKCS #7 \[PKCS7\]은 인증서 벡터의 형식으로 사용되지 않습니다. 또한 PKCS #7은 SEQUENCE가 아닌 SET을 정의하므로 목록 구문 분석 작업이 더 어려워집니다.
서버에서 보낸 인증서에는 다음 규칙이 적용됩니다.
- 명시적으로 협상되지 않는 한\(예: \[TLSPGP\]\) 인증서 유형은 X.509v3이어야 합니다.
- 최종 엔터티 인증서의 공개 키\(및 관련 제한 사항\)는 선택한 키 교환 알고리즘과 호환되어야 합니다.
```text
Key Exchange Alg. Certificate Key Type
RSA RSA public key; the certificate MUST allow the
RSA_PSK key to be used for encryption (the
keyEncipherment bit MUST be set if the key
usage extension is present).
Note: RSA_PSK is defined in [TLSPSK].
DHE_RSA RSA public key; the certificate MUST allow the
ECDHE_RSA key to be used for signing (the
digitalSignature bit MUST be set if the key
usage extension is present) with the signature
scheme and hash algorithm that will be employed
in the server key exchange message.
Note: ECDHE_RSA is defined in [TLSECC].
DHE_DSS DSA public key; the certificate MUST allow the
key to be used for signing with the hash
algorithm that will be employed in the server
key exchange message.
DH_DSS Diffie-Hellman public key; the keyAgreement bit
DH_RSA MUST be set if the key usage extension is
present.
ECDH_ECDSA ECDH-capable public key; the public key MUST
ECDH_RSA use a curve and point format supported by the
client, as described in [TLSECC].
ECDHE_ECDSA ECDSA-capable public key; the certificate MUST
allow the key to be used for signing with the
hash algorithm that will be employed in the
server key exchange message. The public key
MUST use a curve and point format supported by
the client, as described in [TLSECC].
```
- "server\_name" 및 "trusted\_ca\_keys" 확장자\[TLSEXT\]는 인증서 선택을 안내하는 데 사용됩니다.
클라이언트가 "signature\_algorithms" 확장을 제공한 경우 서버에서 제공하는 모든 인증서는 해당 확장에 나타나는 해시/서명 알고리즘 쌍으로 서명되어야 합니다. 이는 하나의 서명 알고리즘에 대한 키를 포함하는 인증서가 다른 서명 알고리즘\(예: DSA 키로 서명된 RSA 키\)을 사용하여 서명될 수 있음을 의미합니다. 이는 알고리즘이 동일해야 하는 TLS 1.1에서 벗어난 것입니다. 이는 또한 DH\_DSS, DH\_RSA, ECDH\_ECDSA 및 ECDH\_RSA 키 교환 알고리즘이 인증서 서명에 사용되는 알고리즘을 제한하지 않는다는 것을 의미합니다. 고정 DH 인증서는 확장 프로그램에 나타나는 해시/서명 알고리즘 쌍으로 서명될 수 있습니다. DH\_DSS, DH\_RSA, ECDH\_ECDSA 및 ECDH\_RSA 이름은 역사적입니다.
서버에 여러 개의 인증서가 있는 경우 위에서 언급한 기준\(전송 계층 끝점, 로컬 구성 및 기본 설정 등과 같은 다른 기준 외에도\)에 따라 인증서 중 하나를 선택합니다. 서버에 단일 인증서가 있는 경우 서버는 이러한 기준을 충족하는지 확인해야 합니다.
현재 TLS와 함께 사용할 수 없는 알고리즘 및/또는 알고리즘 조합을 사용하는 인증서가 있습니다. 예를 들어 RSASSA-PSS 서명 키\(SubjectPublicKeyInfo의 id-RSASSA-PSS OID\)가 있는 인증서는 TLS가 해당 서명 알고리즘을 정의하지 않기 때문에 사용할 수 없습니다.
새로운 키 교환 방법을 지정하는 암호화 제품군이 TLS 프로토콜에 대해 지정되므로 인증서 형식과 필요한 인코딩된 키 정보를 암시합니다.
---
#### **7.4.3. Server Key Exchange Message**
이 메시지가 전송되는 시기:
- 이 메시지는 서버 인증서 메시지\(또는 익명 협상인 경우 ServerHello 메시지\) 직후에 전송됩니다.
- ServerKeyExchange 메시지는 서버 인증서 메시지\(전송된 경우\)에 클라이언트가 프리마스터 비밀을 교환할 수 있을 만큼 충분한 데이터가 포함되지 않은 경우에만 서버에서 전송됩니다. 이는 다음 키 교환 방법에 해당됩니다.
```text
DHE_DSS
DHE_RSA
DH_anon
```
- 다음 키 교환 방법에 대해 ServerKeyExchange 메시지를 보내는 것은 합법적이지 않습니다.
```text
RSA
DH_DSS
DH_RSA
```
- \[TLSECC\]에 정의된 것과 같은 다른 키 교환 알고리즘은 ServerKeyExchange 메시지가 전송되는지 여부를 지정해야 합니다. 메시지가 전송되면 그 내용.
이 메시지의 의미:
- 이 메시지는 클라이언트가 프리마스터 비밀을 전달할 수 있도록 암호화 정보를 전달합니다. 즉, 클라이언트가 키 교환을 완료할 수 있는 Diffie-Hellman 공개 키\(결과적으로 프리마스터 비밀이 됨\) 또는 다른 알고리즘에 대한 공개 키입니다.
이 메시지의 구조:
```text
enum { dhe_dss, dhe_rsa, dh_anon, rsa, dh_dss, dh_rsa
/* may be extended, e.g., for ECDH -- see [TLSECC] */
} KeyExchangeAlgorithm;
struct {
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams; /* Ephemeral DH parameters */
```
- dh\_p Diffie-Hellman 연산에 사용되는 소수 계수입니다.
- dh\_g Diffie-Hellman 작업에 사용되는 생성기입니다.
- dh\_Ys 서버의 Diffie-Hellman 공개 값\(g^X mod p\).
```text
struct {
select (KeyExchangeAlgorithm) {
case dh_anon:
ServerDHParams params;
case dhe_dss:
case dhe_rsa:
ServerDHParams params;
digitally-signed struct {
opaque client_random[32];
opaque server_random[32];
ServerDHParams params;
} signed_params;
case rsa:
case dh_dss:
case dh_rsa:
struct {} ;
/* message is omitted for rsa, dh_dss, and dh_rsa */
/* may be extended, e.g., for ECDH -- see [TLSECC] */
};
} ServerKeyExchange;
```
- params 서버의 키 교환 매개변수입니다.
- signed\_params 비익명 키 교환의 경우 서버의 키 교환 매개변수에 대한 서명입니다.
클라이언트가 "signature\_algorithms" 확장을 제공한 경우 서명 알고리즘과 해시 알고리즘은 해당 확장에 나열된 쌍이어야 합니다. 여기에는 불일치가 발생할 가능성이 있습니다. 예를 들어 클라이언트는 DHE\_DSS 키 교환을 제공하지만 "signature\_algorithms" 확장에서 DSA 쌍을 생략할 수 있습니다. 올바르게 협상하기 위해 서버는 후보 암호 그룹을 선택하기 전에 "signature\_algorithms" 확장에 대해 확인해야 합니다. 이는 다소 우아하지 않지만 원래 암호 제품군 디자인의 변경을 최소화하도록 설계된 절충안입니다.
또한 해시 및 서명 알고리즘은 서버의 최종 엔터티 인증서에 있는 키와 호환되어야 합니다. RSA 키는 허용된 해시 알고리즘과 함께 사용될 수 있으며, 인증서의 제한 사항이 있는 경우 이에 따라 달라질 수 있습니다.
DSA 서명에는 해시 알고리즘에 대한 보안 표시가 포함되어 있지 않기 때문에 임의의 키와 함께 여러 해시를 사용할 수 있는 경우 해시 대체 위험이 있습니다. 현재 DSA\[DSS\]는 SHA-1에서만 사용할 수 있습니다. DSS \[DSS-3\]의 향후 개정판에서는 DSA와 함께 다른 다이제스트 알고리즘의 사용을 허용할 것으로 예상됩니다.
다이제스트 알고리즘은 각 키 크기에 사용해야 합니다. 또한, \[PKIX\]의 향후 개정판에서는 DSA와 함께 사용할 다이제스트 알고리즘을 나타내는 인증서 메커니즘을 지정할 수 있습니다.
새로운 키 교환 알고리즘을 포함하는 TLS에 대해 추가 암호 그룹이 정의되어 있으므로 키 교환 알고리즘과 관련된 인증서 유형이 클라이언트가 프리마스터 비밀을 교환하는 데 충분한 정보를 제공하지 않는 경우에만 서버 키 교환 메시지가 전송됩니다.
---
#### **7.4.4. Certificate Request**
이 메시지가 전송되는 시기:
- 비익명 서버는 선택한 암호화 제품군에 적합한 경우 선택적으로 클라이언트로부터 인증서를 요청할 수 있습니다. 이 메시지는 전송된 경우 ServerKeyExchange 메시지 바로 뒤에 표시됩니다\(전송된 경우에는 이 메시지가 서버의 인증서 메시지 뒤에 표시됩니다\).
이 메시지의 구조:
```text
enum {
rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),
fortezza_dms_RESERVED(20), (255)
} ClientCertificateType;
opaque DistinguishedName<1..2^16-1>;
struct {
ClientCertificateType certificate_types<1..2^8-1>;
SignatureAndHashAlgorithm
supported_signature_algorithms<2^16-1>;
DistinguishedName certificate_authorities<0..2^16-1>;
} CertificateRequest;
```
Certificate\_types - 클라이언트가 제공할 수 있는 인증서 유형 목록입니다.
```text
rsa_sign a certificate containing an RSA key
dss_sign a certificate containing a DSA key
rsa_fixed_dh a certificate containing a static DH key.
dss_fixed_dh a certificate containing a static DH key
```
support\_signature\_algorithms - 서버가 확인할 수 있는 해시/서명 알고리즘 쌍 목록으로, 선호도 내림차순으로 나열됩니다.
Certificate\_authorities - DER 인코딩 형식으로 표시되는 허용되는 인증서 권한의 고유 이름 \[X501\] 목록입니다. 이러한 고유 이름은 루트 CA 또는 하위 CA에 대해 원하는 고유 이름을 지정할 수 있습니다. 따라서 이 메시지는 알려진 루트와 원하는 인증 공간을 설명하는 데 사용될 수 있습니다. Certificate\_authorities 목록이 비어 있는 경우, 반대되는 외부 조정이 없는 한 클라이언트는 적절한 ClientCertificateType의 인증서를 보낼 수 있습니다.
Certificate\_types 및 Supported\_signature\_algorithms 필드의 상호 작용은 다소 복잡합니다. Certificate\_types는 SSLv3부터 TLS에 존재했지만 다소 과소 지정되었습니다. 해당 기능의 대부분은 Supported\_signature\_algorithms로 대체됩니다. 다음 규칙이 적용됩니다.
- 클라이언트가 제공하는 모든 인증서는 Supported\_signature\_algorithms에 있는 해시/서명 알고리즘 쌍을 사용하여 서명되어야 합니다.
- 클라이언트가 제공하는 최종 엔터티 인증서에는 Certificate\_types와 호환되는 키가 포함되어야 합니다. 키가 서명 키인 경우 Supported\_signature\_algorithms의 일부 해시/서명 알고리즘 쌍과 함께 사용할 수 있어야 합니다.
- 기록상의 이유로 일부 클라이언트 인증서 유형의 이름에는 인증서 서명에 사용되는 알고리즘이 포함됩니다. 예를 들어 이전 버전의 TLS에서 rsa\_fixed\_dh는 RSA로 서명되고 정적 DH 키를 포함하는 인증서를 의미했습니다. TLS 1.2에서는 이 기능이 지원되는\_signature\_algorithms에 의해 더 이상 사용되지 않으며 인증서 유형은 더 이상 인증서 서명에 사용되는 알고리즘을 제한하지 않습니다. 예를 들어 서버가 dss\_fixed\_dh 인증서 유형과 {{sha1, dsa}, {sha1, rsa}} 서명 유형을 보내는 경우 클라이언트는 RSA-SHA1로 서명된 정적 DH 키가 포함된 인증서로 응답할 수 있습니다.
새로운 ClientCertificateType 값은 섹션 12에 설명된 대로 IANA에 의해 할당됩니다.
참고: RESERVED로 나열된 값은 사용할 수 없습니다. SSLv3에서 사용되었습니다.
참고: 익명 서버가 클라이언트 인증을 요청하는 것은 치명적인 handshake\_failure 경고입니다.
---
#### **7.4.5. Server Hello Done**
이 메시지가 전송되는 시기:
- ServerHelloDone 메시지는 ServerHello 및 관련 메시지의 끝을 나타내기 위해 서버에서 전송됩니다. 이 메시지를 보낸 후 서버는 클라이언트 응답을 기다립니다.
이 메시지의 의미:
- 이 메시지는 서버가 키 교환을 지원하기 위한 메시지 전송을 완료했으며 클라이언트가 키 교환 단계를 진행할 수 있음을 의미합니다.
- ServerHelloDone 메시지를 수신하면 클라이언트는 필요한 경우 서버가 유효한 인증서를 제공했는지 확인하고 서버 hello 매개변수가 허용되는지 확인해야 합니다.
이 메시지의 구조:
```text
struct { } ServerHelloDone;
```
---
#### **7.4.6. Client Certificate**
이 메시지가 전송되는 시기:
- 클라이언트가 ServerHelloDone 메시지를 받은 후 보낼 수 있는 첫 번째 메시지입니다. 이 메시지는 서버가 인증서를 요청하는 경우에만 전송됩니다. 적합한 인증서를 사용할 수 없는 경우 클라이언트는 인증서가 포함되지 않은 인증서 메시지를 보내야 합니다. 즉, Certificate\_list 구조의 길이는 0입니다. 클라이언트가 인증서를 보내지 않으면 서버는 재량에 따라 클라이언트 인증 없이 핸드셰이크를 계속하거나 치명적인 handshake\_failure 경고로 응답할 수 있습니다. 또한 인증서 체인의 일부 측면이 허용되지 않는 경우\(예: 알려진 신뢰할 수 있는 CA에서 서명하지 않은 경우\) 서버는 재량에 따라 핸드셰이크를 계속하거나\(클라이언트가 인증되지 않은 것으로 간주하여\) 치명적인 경고를 보낼 수 있습니다.
- 클라이언트 인증서는 섹션 7.4.2에 정의된 인증서 구조를 사용하여 전송됩니다.
이 메시지의 의미:
- 이 메시지는 클라이언트의 인증서 체인을 서버에 전달합니다. 서버는 CertificateVerify 메시지를 확인할 때\(클라이언트 인증이 서명을 기반으로 하는 경우\) 또는 프리마스터 비밀을 계산할 때\(일시적이지 않은 Diffie-Hellman의 경우\) 이를 사용합니다. 인증서는 협상된 암호 제품군의 키 교환 알고리즘 및 협상된 확장에 적합해야 합니다.
특히:
- 명시적으로 협상되지 않는 한\(예: \[TLSPGP\]\) 인증서 유형은 X.509v3이어야 합니다.
- 최종 엔터티 인증서의 공개 키\(및 관련 제한 사항\)는 CertificateRequest에 나열된 인증서 유형과 호환되어야 합니다.
```text
Client Cert. Type Certificate Key Type
rsa_sign RSA public key; the certificate MUST allow the
key to be used for signing with the signature
scheme and hash algorithm that will be
employed in the certificate verify message.
dss_sign DSA public key; the certificate MUST allow the
key to be used for signing with the hash
algorithm that will be employed in the
certificate verify message.
ecdsa_sign ECDSA-capable public key; the certificate MUST
allow the key to be used for signing with the
hash algorithm that will be employed in the
certificate verify message; the public key
MUST use a curve and point format supported by
the server.
```
- rsa\_fixed\_dh Diffie-Hellman 공개 키; 서버 키와 동일한 dss\_fixed\_dh 매개변수를 사용해야 합니다.
```text
rsa_fixed_ecdh ECDH-capable public key; MUST use the
ecdsa_fixed_ecdh same curve as the server's key, and MUST use a
point format supported by the server.
```
- 인증서 요청 메시지의 Certificate\_authorities 목록이 비어 있지 않은 경우 인증서 체인의 인증서 중 하나는 나열된 CA 중 하나에서 발급되어야 합니다.
- 인증서는 섹션 7.4.4에 설명된 대로 허용 가능한 해시/서명 알고리즘 쌍을 사용하여 서명되어야 합니다. 이는 이전 버전의 TLS에서 발견된 인증서 서명 알고리즘에 대한 제약을 완화합니다.
서버 인증서와 마찬가지로 현재 TLS와 함께 사용할 수 없는 알고리즘/알고리즘 조합을 사용하는 인증서가 있다는 점에 유의하세요.
---
#### **7.4.7. Client Key Exchange Message**
이 메시지가 전송되는 시기:
- 이 메시지는 항상 클라이언트에 의해 전송됩니다. 전송된 경우 클라이언트 인증서 메시지 바로 뒤에 와야 합니다. 그렇지 않으면 클라이언트가 ServerHelloDone 메시지를 받은 후 보낸 첫 번째 메시지여야 합니다.
이 메시지의 의미:
- 이 메시지를 사용하면 RSA로 암호화된 비밀을 직접 전송하거나 양측이 동일한 프리마스터 비밀에 동의할 수 있도록 하는 Diffie-Hellman 매개변수를 전송하여 프리마스터 비밀이 설정됩니다.
- 클라이언트가 임시 Diffie-Hellman 지수를 사용하는 경우 이 메시지에는 클라이언트의 Diffie-Hellman 공개 값이 포함됩니다. 클라이언트가 정적 DH 지수가 포함된 인증서를 보내는 경우\(즉,fixed\_dh 클라이언트 인증을 수행하는 경우\) 이 메시지를 보내야 하지만 비어 있어야 합니다.
이 메시지의 구조:
- 메시지 선택은 선택한 키 교환 방법에 따라 다릅니다. KeyExchangeAlgorithm 정의는 섹션 7.4.3을 참조하세요.
```text
struct {
select (KeyExchangeAlgorithm) {
case rsa:
EncryptedPreMasterSecret;
case dhe_dss:
case dhe_rsa:
case dh_dss:
case dh_rsa:
case dh_anon:
ClientDiffieHellmanPublic;
} exchange_keys;
} ClientKeyExchange;
```
---
##### **7.4.7.1. RSA-Encrypted Premaster Secret Message**
이 메시지의 의미:
- 키 합의 및 인증에 RSA가 사용되는 경우 클라이언트는 48바이트 프리마스터 비밀을 생성하고 서버 인증서의 공개 키를 사용하여 암호화한 후 암호화된 프리마스터 비밀 메시지로 결과를 보냅니다. 이 구조는 ClientKeyExchange 메시지의 변형이며 그 자체로는 메시지가 아닙니다.
이 메시지의 구조:
```text
struct {
ProtocolVersion client_version;
opaque random[46];
} PreMasterSecret;
```
- client\_version 클라이언트가 지원하는 최신\(최신\) 버전입니다. 버전 롤백 공격을 탐지하는 데 사용됩니다.
```text
random
46 securely-generated random bytes.
struct {
public-key-encrypted PreMasterSecret pre_master_secret;
} EncryptedPreMasterSecret;
```
- pre\_master\_secret 이 무작위 값은 클라이언트에 의해 생성되며 섹션 8.1에 지정된 대로 마스터 비밀을 생성하는 데 사용됩니다.
참고: PreMasterSecret의 버전 번호는 연결을 위해 협상된 버전이 아니라 ClientHello.client\_version에서 클라이언트가 제공하는 버전입니다. 이 기능은 롤백 공격을 방지하도록 설계되었습니다. 불행하게도 일부 이전 구현에서는 협상된 버전을 대신 사용하므로 버전 번호를 확인하면 잘못된 클라이언트 구현과 상호 운용되지 않을 수 있습니다.
클라이언트 구현은 항상 PreMasterSecret에 올바른 버전 번호를 보내야 합니다. ClientHello.client\_version이 TLS 1.1 이상인 경우 서버 구현은 아래 참고 사항에 설명된 대로 버전 번호를 확인해야 합니다. 버전 번호가 TLS 1.0 이하인 경우 서버 구현은 버전 번호를 확인해야 하지만 확인을 비활성화하는 구성 옵션이 있을 수 있습니다. 검사가 실패하면 PreMasterSecret은 아래 설명된 대로 무작위로 지정되어야 합니다.
참고: Bleichenbacher \[BLEI\] 및 Klima et al.이 발견한 공격입니다. \[KPR03\]은 특정 메시지가 해독될 때 적절한 PKCS#1 형식인지, 유효한 PreMasterSecret 구조를 포함하는지 또는 올바른 버전 번호를 가지고 있는지를 밝히는 TLS 서버를 공격하는 데 사용될 수 있습니다.
Klima \[KPR03\]에 설명된 대로 이러한 취약점은 형식이 잘못된 메시지 블록 및/또는 일치하지 않는 버전 번호를 올바른 형식의 RSA 블록과 구별할 수 없는 방식으로 처리함으로써 방지할 수 있습니다. 다시 말해서:
1. 46개의 임의 바이트로 구성된 문자열 R을 생성합니다.
1. 메시지를 해독하여 일반 텍스트 M을 복구합니다.
```text
3. If the PKCS#1 padding is not correct, or the length of message
M is not exactly 48 bytes:
pre_master_secret = ClientHello.client_version || R
else If ClientHello.client_version <= TLS 1.0, and version
number check is explicitly disabled:
pre_master_secret = M
else:
pre_master_secret = ClientHello.client_version || M[2..47]
```
ClientHello.client\_version을 사용하여 pre\_master\_secret을 명시적으로 구성하면 클라이언트가 원래 pre\_master\_secret에서 잘못된 버전을 보낸 경우 잘못된 master\_secret이 생성됩니다.
다른 접근 방식은 버전 번호 불일치를 PKCS-1 형식 오류로 처리하고 프리마스터 비밀을 완전히 무작위화하는 것입니다.
1. 48개의 임의 바이트로 구성된 문자열 R을 생성합니다.
1. 메시지를 해독하여 일반 텍스트 M을 복구합니다.
```text
3. If the PKCS#1 padding is not correct, or the length of message
M is not exactly 48 bytes:
pre_master_secret = R
else If ClientHello.client_version <= TLS 1.0, and version
number check is explicitly disabled:
premaster secret = M
else If M[0..1] != ClientHello.client_version:
premaster secret = R
else:
premaster secret = M
```
이 구성에 대한 실질적인 공격은 알려져 있지 않지만 Klima et al. \[KPR03\]은 몇 가지 이론적 공격을 설명하므로 설명된 첫 번째 구성을 권장합니다.
어떤 경우에도 TLS 서버는 RSA로 암호화된 프리마스터 비밀 메시지 처리가 실패하거나 버전 번호가 예상과 다른 경우 경고를 생성해서는 안 됩니다. 대신 무작위로 생성된 프리마스터 비밀을 사용하여 핸드셰이크를 계속해야 합니다. 문제 해결을 위해 실패의 실제 원인을 기록하는 것이 유용할 수 있습니다. 그러나 정보가 공격자에게 유출되지 않도록 주의해야 합니다\(예: 타이밍, 로그 파일 또는 기타 채널을 통해\).
\[PKCS1\]에 정의된 RSAES-OAEP 암호화 방식은 Bleichenbacher 공격에 대해 더 안전합니다. 그러나 이전 버전의 TLS와의 호환성을 최대화하기 위해 이 사양에서는 RSAES-PKCS1-v1\_5 체계를 사용합니다. 위의 권장 사항을 준수하는 경우 Bleichenbacher 공격의 변종은 존재하지 않는 것으로 알려져 있습니다.
구현 참고 사항: 공개 키로 암호화된 데이터는 불투명 벡터 <0..2^16-1\>로 표시됩니다\(섹션 4.7 참조\). 따라서 ClientKeyExchange의 RSA로 암호화된 PreMasterSecret 앞에는 2바이트 길이가 옵니다. EncryptedPreMasterSecret이 ClientKeyExchange의 유일한 데이터이고 길이가 명확하게 결정될 수 있기 때문에 RSA의 경우 이러한 바이트는 중복됩니다. SSLv3 사양은 공개 키로 암호화된 데이터의 인코딩에 대해 명확하지 않았으므로 많은 SSLv3 구현에서는 길이 바이트를 포함하지 않습니다. 즉, RSA로 암호화된 데이터를 ClientKeyExchange 메시지에 직접 인코딩합니다.
이 사양에서는 길이 바이트로 완전한 EncryptedPreMasterSecret의 올바른 인코딩이 필요합니다. 결과 PDU는 많은 SSLv3 구현과 호환되지 않습니다. 구현자
SSLv3에서 업그레이드하는 경우 올바른 인코딩을 생성하고 허용하도록 구현을 수정해야 합니다. SSLv3 및 TLS와 모두 호환되기를 원하는 구현자는 구현 동작을 프로토콜 버전에 따라 다르게 만들어야 합니다.
구현 참고 사항: 이제 적어도 클라이언트와 서버가 동일한 LAN에 있을 때 TLS에 대한 원격 타이밍 기반 공격이 가능하다는 것이 알려져 있습니다. 따라서 정적 RSA 키를 사용하는 구현은 \[TIMING\]에 설명된 대로 RSA 블라인드 또는 다른 타이밍 방지 기술을 사용해야 합니다.
---
##### **7.4.7.2. Client Diffie-Hellman Public Value**
이 메시지의 의미:
- 이 구조는 클라이언트의 인증서에 아직 포함되지 않은 경우 클라이언트의 Diffie-Hellman 공개 값\(Yc\)을 전달합니다. Yc에 사용되는 인코딩은 열거된 PublicValueEncoding에 의해 결정됩니다. 이 구조는 클라이언트 키 교환 메시지의 변형이며 메시지 자체는 아닙니다.
이 메시지의 구조:
```text
enum { implicit, explicit } PublicValueEncoding;
```
- 암시적 클라이언트가 적절한 Diffie-Hellman 키\(fixed\_dh 클라이언트 인증용\)가 포함된 인증서를 보낸 경우 Yc는 암시적이므로 다시 보낼 필요가 없습니다. 이 경우 클라이언트 키 교환 메시지가 전송되지만 비어 있어야 합니다.
- 명시적인 Yc를 보내야 합니다.
```text
struct {
select (PublicValueEncoding) {
case implicit: struct { };
case explicit: opaque dh_Yc<1..2^16-1>;
} dh_public;
} ClientDiffieHellmanPublic;
```
- dh\_Yc 클라이언트의 Diffie-Hellman 공개 값\(Yc\)입니다.
---
#### **7.4.8. Certificate Verify**
이 메시지가 전송되는 시기:
- 이 메시지는 클라이언트 인증서의 명시적인 확인을 제공하는 데 사용됩니다. 이 메시지는 서명 기능이 있는 클라이언트 인증서\(즉, 고정된 Diffie-Hellman 매개변수가 포함된 인증서를 제외한 모든 인증서\) 다음에만 전송됩니다. 전송되면 클라이언트 키 교환 메시지 바로 뒤에 와야 합니다.
이 메시지의 구조:
```text
struct {
digitally-signed struct {
opaque handshake_messages[handshake_messages_length];
}
} CertificateVerify;
```
- 여기서 handshake\_messages는 클라이언트 hello에서 시작하여 이 메시지를 포함하지 않고 핸드셰이크 메시지의 유형 및 길이 필드를 포함하여 보내거나 받은 모든 핸드셰이크 메시지를 나타냅니다. 이는 지금까지 교환된 모든 Handshake 구조\(섹션 7.4에 정의됨\)를 연결한 것입니다. 이를 위해서는 양측이 CertificateVerify 계산 시점까지 모든 잠재적 해시 알고리즘에 대해 메시지를 버퍼링하거나 실행 중인 해시를 계산해야 합니다. 서버는 CertificateRequest 메시지에 제한된 다이제스트 알고리즘 세트를 제공하여 이 계산 비용을 최소화할 수 있습니다.
- 서명에 사용되는 해시 및 서명 알고리즘은 CertificateRequest 메시지의 Supported\_signature\_algorithms 필드에 있는 것 중 하나여야 합니다. 또한 해시 및 서명 알고리즘은 클라이언트의 최종 엔터티 인증서에 있는 키와 호환되어야 합니다. RSA 키는 허용된 해시 알고리즘과 함께 사용될 수 있으며, 인증서의 제한 사항이 있는 경우 이에 따라 달라질 수 있습니다.
- DSA 서명에는 해시 알고리즘에 대한 보안 표시가 포함되어 있지 않으므로 키와 함께 여러 해시를 사용할 수 있는 경우 해시 대체 위험이 있습니다. 현재 DSA\[DSS\]는 SHA-1에서만 사용할 수 있습니다. DSS \[DSS-3\]의 향후 개정판에서는 DSA와 함께 다른 다이제스트 알고리즘을 사용할 수 있을 뿐만 아니라 각 키 크기에 어떤 다이제스트 알고리즘을 사용해야 하는지에 대한 지침도 허용될 것으로 예상됩니다. 또한, \[PKIX\]의 향후 개정판에서는 DSA와 함께 사용할 다이제스트 알고리즘을 나타내는 인증서 메커니즘을 지정할 수 있습니다.
---
#### **7.4.9. Finished**
이 메시지가 전송되는 시기:
- 키 교환 및 인증 프로세스가 성공했는지 확인하기 위해 암호 사양 변경 메시지 직후에 항상 Finished 메시지가 전송됩니다. 다른 핸드셰이크 메시지와 완료 메시지 사이에 암호 사양 변경 메시지를 수신하는 것이 중요합니다.
이 메시지의 의미:
- Finished 메시지는 방금 협상된 알고리즘, 키, 비밀로 보호되는 첫 번째 메시지입니다. Finished 메시지의 수신자는 내용이 올바른지 확인해야 합니다. 한쪽에서 Finished 메시지를 보내고 피어로부터 Finished 메시지를 수신하고 확인한 후에는 연결을 통해 애플리케이션 데이터를 보내고 받기 시작할 수 있습니다.
이 메시지의 구조:
```text
struct {
opaque verify_data[verify_data_length];
} Finished;
verify_data
PRF(master_secret, finished_label, Hash(handshake_messages))
[0..verify_data_length-1];
```
- finished\_label 클라이언트가 보낸 완료 메시지의 경우 "클라이언트 완료" 문자열입니다. 서버에서 보낸 완료 메시지의 경우 문자열 "서버 완료"입니다.
- 해시는 핸드셰이크 메시지의 해시를 나타냅니다. 섹션 5에 정의된 PRF의 경우 해시는 PRF의 기초로 사용되는 해시여야 합니다. 다른 PRF를 정의하는 모든 암호 제품군은 완료된 계산에 사용할 해시도 정의해야 합니다.
- 이전 버전의 TLS에서는 verify\_data 길이가 항상 12옥텟이었습니다. 현재 버전의 TLS에서는 암호화 제품군에 따라 다릅니다. verify\_data\_length를 명시적으로 지정하지 않은 모든 암호 제품군의 verify\_data\_length는 12입니다. 여기에는 기존 암호 제품군이 모두 포함됩니다. 이 표현은 이전 버전과 동일한 인코딩을 가지고 있습니다. 향후 암호 제품군에서는 다른 길이를 지정할 수 있지만 해당 길이는 최소 12바이트여야 합니다.
- handshake\_messages 이 핸드셰이크의 모든 메시지\(HelloRequest 메시지는 포함하지 않음\)에서 이 메시지까지\(포함하지 않음\)의 모든 데이터입니다. 이는 핸드셰이크 레이어에서만 볼 수 있는 데이터이며 레코드 레이어 헤더를 포함하지 않습니다. 이는 지금까지 교환된 섹션 7.4에 정의된 모든 Handshake 구조의 연결입니다.
핸드셰이크의 적절한 지점에서 Finished 메시지 앞에 ChangeCipherSpec 메시지가 나오지 않는 경우 이는 치명적인 오류입니다.
handshake\_messages 값에는 ClientHello에서 시작하여 이 Finished 메시지까지의 모든 핸드셰이크 메시지가 포함됩니다. 이는 CertificateVerify 메시지\(전송된 경우\)를 포함하므로 섹션 7.4.8의 handshake\_messages와 다를 수 있습니다. 또한 클라이언트가 보낸 Finished 메시지의 handshake\_messages는 두 번째로 보낸 메시지에 이전 메시지가 포함되므로 서버가 보낸 Finished 메시지의 handshake\_messages와 다릅니다.
참고: ChangeCipherSpec 메시지, 경고 및 기타 레코드 유형은 핸드셰이크 메시지가 아니며 해시 계산에 포함되지 않습니다. 또한 HelloRequest 메시지는 핸드셰이크 해시에서 생략됩니다.
---
## **8. Cryptographic Computations**
연결 보호를 시작하려면 TLS 레코드 프로토콜에는 일련의 알고리즘, 마스터 비밀, 클라이언트 및 서버 임의 값의 사양이 필요합니다. 인증, 암호화 및 MAC 알고리즘은 서버에서 선택한 cipher\_suite에 의해 결정되고 ServerHello 메시지에 표시됩니다. 압축 알고리즘은 hello 메시지에서 협상되며, hello 메시지에서는 임의의 값이 교환됩니다. 이제 남은 것은 마스터 시크릿을 계산하는 것뿐입니다.
---
### **8.1. Computing the Master Secret**
모든 키 교환 방법에 대해 동일한 알고리즘을 사용하여 pre\_master\_secret을 master\_secret으로 변환합니다. pre\_master\_secret은 master\_secret이 계산된 후에 메모리에서 삭제되어야 합니다.
```text
master_secret = PRF(pre_master_secret, "master secret",
ClientHello.random + ServerHello.random)
[0..47];
```
마스터 시크릿의 길이는 항상 정확히 48바이트입니다. 프리마스터 비밀의 길이는 키 교환 방법에 따라 달라집니다.
---
#### **8.1.1. RSA**
RSA가 서버 인증 및 키 교환에 사용되는 경우 48바이트 pre\_master\_secret이 클라이언트에 의해 생성되고 서버의 공개 키로 암호화되어 서버로 전송됩니다. 서버는 개인 키를 사용하여 pre\_master\_secret을 해독합니다. 그런 다음 양 당사자는 위에 지정된 대로 pre\_master\_secret을 master\_secret으로 변환합니다.
---
#### **8.1.2. Diffie-Hellman**
일반적인 Diffie-Hellman 계산이 수행됩니다. 협상된 키\(Z\)는 pre\_master\_secret으로 사용되며 위에서 지정한 대로 master\_secret으로 변환됩니다. 모두 0 비트를 포함하는 Z의 선행 바이트는 pre\_master\_secret으로 사용되기 전에 제거됩니다.
참고: Diffie-Hellman 매개변수는 서버에 의해 지정되며 일시적이거나 서버 인증서 내에 포함될 수 있습니다.
---
## **9. Mandatory Cipher Suites**
달리 지정하는 애플리케이션 프로필 표준이 없는 경우 TLS 호환 애플리케이션은 암호화 제품군 TLS\_RSA\_WITH\_AES\_128\_CBC\_SHA를 구현해야 합니다\(정의는 부록 A.5 참조\).
---
## **10. Application Data Protocol**
애플리케이션 데이터 메시지는 레코드 계층에 의해 전달되며 현재 연결 상태에 따라 조각화, 압축 및 암호화됩니다. 메시지는 레코드 레이어에 투명한 데이터로 처리됩니다.
---
## **11. Security Considerations**
보안 문제는 이 메모 전체, 특히 부록 D, E, F에서 논의됩니다.
---
## **12. IANA Considerations**
이 문서는 원래 \[TLS1.1\]에서 생성된 여러 레지스트리를 사용합니다. IANA는 이 문서를 참조하기 위해 이를 업데이트했습니다. 레지스트리 및 해당 할당 정책\(\[TLS1.1\]에서 변경되지 않음\)은 아래에 나열되어 있습니다.
- TLS ClientCertificateType 식별자 레지스트리: 0-63\(십진수\) 범위의 미래 값은 표준 조치 \[RFC2434\]를 통해 할당됩니다. 64-223\(십진수\) 범위의 값은 사양 필수 \[RFC2434\]를 통해 할당됩니다. 224-255\(십진수\) 범위의 값은 개인용으로 예약되어 있습니다\[RFC2434\].
- TLS Cipher Suite Registry: 0-191\(십진수\) 범위의 첫 번째 바이트를 포함하는 미래 값은 표준 조치 \[RFC2434\]를 통해 할당됩니다. 192-254\(십진수\) 범위의 첫 번째 바이트 값은 사양 필수 \[RFC2434\]를 통해 할당됩니다. 첫 번째 바이트 255\(10진수\)의 값은 개인용으로 예약되어 있습니다\[RFC2434\].
- 이 문서는 TLS Cipher Suite 레지스트리에서 할당된 값\(부록 A.5\)을 포함하는 몇 가지 새로운 HMAC-SHA256 기반 암호 제품군을 정의합니다.
- TLS ContentType 레지스트리: 표준 조치 \[RFC2434\]를 통해 미래 값이 할당됩니다.
- TLS 경고 레지스트리: 표준 조치 \[RFC2434\]를 통해 미래 값이 할당됩니다.
- TLS HandshakeType 레지스트리: 표준 조치 \[RFC2434\]를 통해 미래 값이 할당됩니다.
이 문서는 또한 원래 \[RFC4366\]에서 생성된 레지스트리를 사용합니다. IANA는 이 문서를 참조하도록 업데이트했습니다. 레지스트리 및 해당 할당 정책\(\[RFC4366\]에서 변경되지 않음\)은 다음과 같습니다.
- TLS ExtensionType 레지스트리: 미래 값은 IETF 합의 \[RFC2434\]를 통해 할당됩니다. IANA는 서명\_알고리즘 확장 및 해당 값을 포함하도록 이 레지스트리를 업데이트했습니다\(섹션 7.4.1.4 참조\).
또한 이 문서는 IANA가 유지 관리할 두 가지 새로운 레지스트리를 정의합니다.
- TLS SignatureAlgorithm 레지스트리: 레지스트리는 처음에 섹션 7.4.1.4.1에 설명된 값으로 채워졌습니다. 0-63\(십진수\) 범위의 미래 값은 표준 조치 \[RFC2434\]를 통해 할당됩니다. 64-223\(십진수\) 범위의 값은 사양 필수 \[RFC2434\]를 통해 할당됩니다. 224-255\(십진수\) 범위의 값은 개인용으로 예약되어 있습니다\[RFC2434\].
- TLS HashAlgorithm 레지스트리: 레지스트리는 처음에 섹션 7.4.1.4.1에 설명된 값으로 채워졌습니다. 0-63\(십진수\) 범위의 미래 값은 표준 조치 \[RFC2434\]를 통해 할당됩니다. 64-223\(십진수\) 범위의 값은 사양 필수 \[RFC2434\]를 통해 할당됩니다. 224-255\(십진수\) 범위의 값은 개인용으로 예약되어 있습니다\[RFC2434\].
- 이 문서는 \[RFC3749\]에 정의된 TLS 압축 방법 식별자 레지스트리도 사용합니다. IANA는 "null" 압축 방법에 값 0을 할당했습니다.
---
# **Appendix A. Protocol Data Structures and Constant Values**
이 섹션에서는 프로토콜 유형과 상수에 대해 설명합니다.
---
### **A.1. Record Layer**
```text
struct {
uint8 major;
uint8 minor;
} ProtocolVersion;
ProtocolVersion version = { 3, 3 }; /* TLS v1.2*/
enum {
change_cipher_spec(20), alert(21), handshake(22),
application_data(23), (255)
} ContentType;
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSPlaintext.length];
} TLSPlaintext;
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
opaque fragment[TLSCompressed.length];
} TLSCompressed;
struct {
ContentType type;
ProtocolVersion version;
uint16 length;
select (SecurityParameters.cipher_type) {
case stream: GenericStreamCipher;
case block: GenericBlockCipher;
case aead: GenericAEADCipher;
} fragment;
} TLSCiphertext;
stream-ciphered struct {
opaque content[TLSCompressed.length];
opaque MAC[SecurityParameters.mac_length];
} GenericStreamCipher;
struct {
opaque IV[SecurityParameters.record_iv_length];
block-ciphered struct {
opaque content[TLSCompressed.length];
opaque MAC[SecurityParameters.mac_length];
uint8 padding[GenericBlockCipher.padding_length];
uint8 padding_length;
};
} GenericBlockCipher;
struct {
opaque nonce_explicit[SecurityParameters.record_iv_length];
aead-ciphered struct {
opaque content[TLSCompressed.length];
};
} GenericAEADCipher;
```
---
### **A.2. Change Cipher Specs Message**
```text
struct {
enum { change_cipher_spec(1), (255) } type;
} ChangeCipherSpec;
```
---
### **A.3. Alert Messages**
```text
enum { warning(1), fatal(2), (255) } AlertLevel;
enum {
close_notify(0),
unexpected_message(10),
bad_record_mac(20),
decryption_failed_RESERVED(21),
record_overflow(22),
decompression_failure(30),
handshake_failure(40),
no_certificate_RESERVED(41),
bad_certificate(42),
unsupported_certificate(43),
certificate_revoked(44),
certificate_expired(45),
certificate_unknown(46),
illegal_parameter(47),
unknown_ca(48),
access_denied(49),
decode_error(50),
decrypt_error(51),
export_restriction_RESERVED(60),
protocol_version(70),
insufficient_security(71),
internal_error(80),
user_canceled(90),
no_renegotiation(100),
unsupported_extension(110), /* new */
(255)
} AlertDescription;
struct {
AlertLevel level;
AlertDescription description;
} Alert;
```
---
### **A.4. Handshake Protocol**
```text
enum {
hello_request(0), client_hello(1), server_hello(2),
certificate(11), server_key_exchange (12),
certificate_request(13), server_hello_done(14),
certificate_verify(15), client_key_exchange(16),
finished(20)
(255)
} HandshakeType;
struct {
HandshakeType msg_type;
uint24 length;
select (HandshakeType) {
case hello_request: HelloRequest;
case client_hello: ClientHello;
case server_hello: ServerHello;
case certificate: Certificate;
case server_key_exchange: ServerKeyExchange;
case certificate_request: CertificateRequest;
case server_hello_done: ServerHelloDone;
case certificate_verify: CertificateVerify;
case client_key_exchange: ClientKeyExchange;
case finished: Finished;
} body;
} Handshake;
```
---
#### **A.4.1. Hello Messages**
```text
struct { } HelloRequest;
struct {
uint32 gmt_unix_time;
opaque random_bytes[28];
} Random;
opaque SessionID<0..32>;
uint8 CipherSuite[2];
enum { null(0), (255) } CompressionMethod;
struct {
ProtocolVersion client_version;
Random random;
SessionID session_id;
CipherSuite cipher_suites<2..2^16-2>;
CompressionMethod compression_methods<1..2^8-1>;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ClientHello;
struct {
ProtocolVersion server_version;
Random random;
SessionID session_id;
CipherSuite cipher_suite;
CompressionMethod compression_method;
select (extensions_present) {
case false:
struct {};
case true:
Extension extensions<0..2^16-1>;
};
} ServerHello;
struct {
ExtensionType extension_type;
opaque extension_data<0..2^16-1>;
} Extension;
enum {
signature_algorithms(13), (65535)
} ExtensionType;
enum{
none(0), md5(1), sha1(2), sha224(3), sha256(4), sha384(5),
sha512(6), (255)
} HashAlgorithm;
enum {
anonymous(0), rsa(1), dsa(2), ecdsa(3), (255)
} SignatureAlgorithm;
struct {
HashAlgorithm hash;
SignatureAlgorithm signature;
} SignatureAndHashAlgorithm;
SignatureAndHashAlgorithm
supported_signature_algorithms<2..2^16-1>;
```
---
#### **A.4.2. Server Authentication and Key Exchange Messages**
```text
opaque ASN.1Cert<2^24-1>;
struct {
ASN.1Cert certificate_list<0..2^24-1>;
} Certificate;
enum { dhe_dss, dhe_rsa, dh_anon, rsa,dh_dss, dh_rsa
/* may be extended, e.g., for ECDH -- see [TLSECC] */
} KeyExchangeAlgorithm;
struct {
opaque dh_p<1..2^16-1>;
opaque dh_g<1..2^16-1>;
opaque dh_Ys<1..2^16-1>;
} ServerDHParams; /* Ephemeral DH parameters */
struct {
select (KeyExchangeAlgorithm) {
case dh_anon:
ServerDHParams params;
case dhe_dss:
case dhe_rsa:
ServerDHParams params;
digitally-signed struct {
opaque client_random[32];
opaque server_random[32];
ServerDHParams params;
} signed_params;
case rsa:
case dh_dss:
case dh_rsa:
struct {} ;
/* message is omitted for rsa, dh_dss, and dh_rsa */
/* may be extended, e.g., for ECDH -- see [TLSECC] */
} ServerKeyExchange;
enum {
rsa_sign(1), dss_sign(2), rsa_fixed_dh(3), dss_fixed_dh(4),
rsa_ephemeral_dh_RESERVED(5), dss_ephemeral_dh_RESERVED(6),
fortezza_dms_RESERVED(20),
(255)
} ClientCertificateType;
opaque DistinguishedName<1..2^16-1>;
struct {
ClientCertificateType certificate_types<1..2^8-1>;
DistinguishedName certificate_authorities<0..2^16-1>;
} CertificateRequest;
struct { } ServerHelloDone;
```
---
#### **A.4.3. Client Authentication and Key Exchange Messages**
```text
struct {
select (KeyExchangeAlgorithm) {
case rsa:
EncryptedPreMasterSecret;
case dhe_dss:
case dhe_rsa:
case dh_dss:
case dh_rsa:
case dh_anon:
ClientDiffieHellmanPublic;
} exchange_keys;
} ClientKeyExchange;
struct {
ProtocolVersion client_version;
opaque random[46];
} PreMasterSecret;
struct {
public-key-encrypted PreMasterSecret pre_master_secret;
} EncryptedPreMasterSecret;
enum { implicit, explicit } PublicValueEncoding;
struct {
select (PublicValueEncoding) {
case implicit: struct {};
case explicit: opaque DH_Yc<1..2^16-1>;
} dh_public;
} ClientDiffieHellmanPublic;
struct {
digitally-signed struct {
opaque handshake_messages[handshake_messages_length];
}
} CertificateVerify;
```
---
#### **A.4.4. Handshake Finalization Message**
```text
struct {
opaque verify_data[verify_data_length];
} Finished;
```
---
### **A.5. The Cipher Suite**
다음 값은 ClientHello 및 ServerHello 메시지에 사용되는 암호 제품군 코드를 정의합니다.
암호 제품군은 TLS 버전 1.2에서 지원되는 암호 사양을 정의합니다.
TLS\_NULL\_WITH\_NULL\_NULL이 지정되고 해당 채널의 첫 번째 핸드셰이크 중 TLS 연결의 초기 상태이지만 보안되지 않은 연결보다 더 많은 보호를 제공하지 않으므로 협상해서는 안 됩니다.
```text
CipherSuite TLS_NULL_WITH_NULL_NULL = { 0x00,0x00 };
```
다음 CipherSuite 정의에서는 서버가 키 교환에 사용할 수 있는 RSA 인증서를 제공해야 합니다. 서버는 인증서 요청 메시지에서 서명 가능 인증서를 요청할 수 있습니다.
```text
CipherSuite TLS_RSA_WITH_NULL_MD5 = { 0x00,0x01 };
CipherSuite TLS_RSA_WITH_NULL_SHA = { 0x00,0x02 };
CipherSuite TLS_RSA_WITH_NULL_SHA256 = { 0x00,0x3B };
CipherSuite TLS_RSA_WITH_RC4_128_MD5 = { 0x00,0x04 };
CipherSuite TLS_RSA_WITH_RC4_128_SHA = { 0x00,0x05 };
CipherSuite TLS_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0A };
CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA = { 0x00,0x2F };
CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA = { 0x00,0x35 };
CipherSuite TLS_RSA_WITH_AES_128_CBC_SHA256 = { 0x00,0x3C };
CipherSuite TLS_RSA_WITH_AES_256_CBC_SHA256 = { 0x00,0x3D };
```
다음 암호 그룹 정의는 서버 인증\(및 선택적으로 클라이언트 인증\) Diffie-Hellman에 사용됩니다. DH는 서버 인증서에 인증 기관\(CA\)이 서명한 Diffie-Hellman 매개변수가 포함된 암호 제품군을 나타냅니다. DHE는 임시 Diffie-Hellman을 나타냅니다. 여기서 Diffie-Hellman 매개변수는 CA에서 서명한 서명 가능 인증서로 서명됩니다. 서버에서 사용하는 서명 알고리즘은 CipherSuite 이름의 DHE 구성 요소 뒤에 지정됩니다. 서버는 클라이언트 인증을 위해 클라이언트로부터 서명 가능 인증서를 요청하거나 Diffie-Hellman 인증서를 요청할 수 있습니다. 클라이언트가 제공하는 모든 Diffie-Hellman 인증서는 서버에서 설명하는 매개변수\(그룹 및 생성기\)를 사용해야 합니다.
```text
CipherSuite TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x0D };
CipherSuite TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x10 };
CipherSuite TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA = { 0x00,0x13 };
CipherSuite TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA = { 0x00,0x16 };
CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA = { 0x00,0x30 };
CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA = { 0x00,0x31 };
CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA = { 0x00,0x32 };
CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA = { 0x00,0x33 };
CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA = { 0x00,0x36 };
CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA = { 0x00,0x37 };
CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA = { 0x00,0x38 };
CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA = { 0x00,0x39 };
CipherSuite TLS_DH_DSS_WITH_AES_128_CBC_SHA256 = { 0x00,0x3E };
CipherSuite TLS_DH_RSA_WITH_AES_128_CBC_SHA256 = { 0x00,0x3F };
CipherSuite TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 = { 0x00,0x40 };
CipherSuite TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 = { 0x00,0x67 };
CipherSuite TLS_DH_DSS_WITH_AES_256_CBC_SHA256 = { 0x00,0x68 };
CipherSuite TLS_DH_RSA_WITH_AES_256_CBC_SHA256 = { 0x00,0x69 };
CipherSuite TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 = { 0x00,0x6A };
CipherSuite TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 = { 0x00,0x6B };
```
다음 암호 제품군은 어느 쪽도 인증되지 않은 완전한 익명의 Diffie-Hellman 통신에 사용됩니다. 이 모드는 중간자 공격에 취약합니다. 따라서 이 모드를 사용하는 것은 제한적으로 사용됩니다. 애플리케이션 계층에서 익명 키 교환을 허용하도록 특별히 요청하지 않는 한 TLS 1.2 구현에서는 이러한 암호 제품군을 사용해서는 안 됩니다. \(예를 들어, 인증 설정이 없거나 인증을 보장하기 위한 다른 수단이 있는 보다 복잡한 보안 프로토콜의 일부로 TLS가 사용되는 경우 기회주의적 암호화를 지원하기 위해 익명 키 교환이 허용되는 경우도 있습니다.\)
```text
CipherSuite TLS_DH_anon_WITH_RC4_128_MD5 = { 0x00,0x18 };
CipherSuite TLS_DH_anon_WITH_3DES_EDE_CBC_SHA = { 0x00,0x1B };
CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA = { 0x00,0x34 };
CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA = { 0x00,0x3A };
CipherSuite TLS_DH_anon_WITH_AES_128_CBC_SHA256 = { 0x00,0x6C };
CipherSuite TLS_DH_anon_WITH_AES_256_CBC_SHA256 = { 0x00,0x6D };
```
실제로 키 교환을 확인하지 않고 비익명 키 교환을 사용하는 것은 본질적으로 익명 키 교환과 동일하며 동일한 예방 조치가 적용됩니다. 비익명 키 교환은 일반적으로 익명 키 교환보다 더 높은 계산 및 통신 비용을 포함하지만 애플리케이션 계층에서 익명 키 교환을 허용할 때 비익명 키 교환을 비활성화하지 않는 것이 상호 운용성에 도움이 될 수 있습니다.
섹션 12에 설명된 대로 IANA에서 새로운 암호 그룹 값을 할당했습니다.
참고: 암호화 제품군 값 { 0x00, 0x1C } 및 { 0x00, 0x1D }는 SSL 3의 Fortezza 기반 암호화 제품군과의 충돌을 방지하기 위해 예약되어 있습니다.
---
### **A.6. The Security Parameters**
이러한 보안 매개변수는 TLS 핸드셰이크 프로토콜에 의해 결정되며 연결 상태를 초기화하기 위해 TLS 레코드 계층에 매개변수로 제공됩니다. SecurityParameters에는 다음이 포함됩니다.
```text
enum { null(0), (255) } CompressionMethod;
enum { server, client } ConnectionEnd;
enum { tls_prf_sha256 } PRFAlgorithm;
enum { null, rc4, 3des, aes } BulkCipherAlgorithm;
enum { stream, block, aead } CipherType;
enum { null, hmac_md5, hmac_sha1, hmac_sha256, hmac_sha384,
hmac_sha512} MACAlgorithm;
/* Other values may be added to the algorithms specified in
CompressionMethod, PRFAlgorithm, BulkCipherAlgorithm, and
MACAlgorithm. */
struct {
ConnectionEnd entity;
PRFAlgorithm prf_algorithm;
BulkCipherAlgorithm bulk_cipher_algorithm;
CipherType cipher_type;
uint8 enc_key_length;
uint8 block_length;
uint8 fixed_iv_length;
uint8 record_iv_length;
MACAlgorithm mac_algorithm;
uint8 mac_length;
uint8 mac_key_length;
CompressionMethod compression_algorithm;
opaque master_secret[48];
opaque client_random[32];
opaque server_random[32];
} SecurityParameters;
```
---
### **A.7. Changes to RFC 4492**
RFC 4492 \[TLSECC\]는 TLS에 Elliptic Curve 암호화 제품군을 추가합니다. 이 문서는 해당 문서에 사용된 일부 구조를 변경합니다. 이 섹션에서는 RFC 4492 및 TLS 1.2 구현자에게 필요한 변경 사항을 자세히 설명합니다. RFC 4492를 구현하지 않는 TLS 1.2 구현자는 이 섹션을 읽을 필요가 없습니다.
이 문서에서는 서명을 생성하는 데 사용되는 서명 및 다이제스트 알고리즘을 식별하기 위해 디지털 서명된 요소에 "signature\_algorithm" 필드를 추가합니다. 이 변경 사항은 ECDSA를 사용하여 형성된 디지털 서명에도 적용되므로 ECDSA 서명을 SHA-1 이외의 다이제스트 알고리즘과 함께 사용할 수 있습니다. 단, 이러한 사용은 인증서 및 \[PKIX\]의 향후 개정판에 부과된 모든 제한 사항과 호환됩니다.
섹션 7.4.2 및 7.4.6에 설명된 대로 인증서 서명에 사용되는 서명 알고리즘에 대한 제한은 더 이상 암호 제품군\(서버에서 사용되는 경우\) 또는 ClientCertificateType\(클라이언트에서 사용되는 경우\)에 묶여 있지 않습니다. 따라서 RFC 4492의 섹션 2 및 3에 지정된 인증서 서명에 사용되는 알고리즘에 대한 제한도 완화되었습니다. 이 문서에서와 같이 최종 엔터티 인증서의 키에 대한 제한 사항은 그대로 유지됩니다.
---
# **Appendix B. Glossary**
AES\(고급 암호화 표준\) - AES \[AES\]는 널리 사용되는 대칭 암호화 알고리즘입니다. AES는 128, 192 또는 256비트 키와 16바이트 블록 크기를 갖는 블록 암호입니다. TLS는 현재 128비트 및 256비트 키 크기만 지원합니다.
애플리케이션 프로토콜 - 애플리케이션 프로토콜은 일반적으로 전송 계층\(예: TCP/IP\) 바로 위에 계층을 이루는 프로토콜입니다. 예로는 HTTP, TELNET, FTP 및 SMTP가 있습니다.
```text
asymmetric cipher
See public key cryptography.
```
AEAD\(추가 데이터를 사용한 인증된 암호화\) - 기밀성과 메시지 무결성을 동시에 제공하는 대칭 암호화 알고리즘입니다.
인증 - 인증은 한 엔터티가 다른 엔터티의 신원을 확인하는 기능입니다.
블록 암호 - 블록 암호는 블록이라고 하는 비트 그룹의 일반 텍스트에서 작동하는 알고리즘입니다. 64비트는 128비트가 일반적인 블록 크기입니다.
대량 암호 - 대량의 데이터를 암호화하는 데 사용되는 대칭 암호화 알고리즘입니다.
CBC\(암호 블록 체인\) - CBC는 블록 암호로 암호화된 모든 일반 텍스트 블록이 먼저 이전 암호 텍스트 블록\(또는 첫 번째 블록의 경우 초기화 벡터\)과 배타적 OR로 연결되는 모드입니다. 해독을 위해 모든 블록은 먼저 해독된 다음 이전 암호문 블록\(또는 IV\)과 배타적 OR로 연결됩니다.
인증서 - X.509 프로토콜\(ISO 인증 프레임워크라고도 함\)의 일부로 인증서는 신뢰할 수 있는 인증 기관에 의해 할당되며 당사자의 ID 또는 기타 속성과 공개 키 간의 강력한 바인딩을 제공합니다.
클라이언트 - 서버에 대한 TLS 연결을 시작하는 애플리케이션 엔터티입니다. 이는 클라이언트가 기본 전송 연결을 시작했음을 의미할 수도 있고 의미하지 않을 수도 있습니다. 서버와 클라이언트의 주요 작동 차이점은 서버는 일반적으로 인증되는 반면 클라이언트는 선택적으로만 인증된다는 것입니다.
클라이언트 쓰기 키 - 클라이언트가 쓴 데이터를 암호화하는 데 사용되는 키입니다.
클라이언트 쓰기 MAC 키 - 클라이언트가 작성한 데이터를 인증하는 데 사용되는 비밀 데이터입니다.
연결 - 연결은 적절한 유형의 서비스를 제공하는 전송\(OSI 계층화 모델 정의에서\)입니다. TLS의 경우 이러한 연결은 P2P 관계입니다. 연결은 일시적입니다. 모든 연결은 하나의 세션과 연결됩니다.
데이터 암호화 표준 - DES \[DES\]는 지금은 다소 약한 것으로 간주되지만 여전히 매우 널리 사용되는 대칭 암호화 알고리즘입니다. DES는 56비트 키와 8바이트 블록 크기를 가진 블록 암호입니다. TLS에서는 키 생성 목적으로 DES가 8바이트 키 길이\(64비트\)를 갖는 것으로 처리되지만 여전히 56비트만 제공합니다.
- 보호의. \(각 키 바이트의 낮은 비트는 해당 키 바이트에서 홀수 패리티를 생성하도록 설정되는 것으로 추정됩니다.\) DES는 또한 각 데이터 블록에 대해 3개의 독립 키와 3개의 암호화가 사용되는 모드\[3DES\]에서 작동할 수 있습니다. 이는 168비트 키\(TLS 키 생성 방법에서는 24바이트\)를 사용하며 112비트 보안에 해당합니다.
디지털 서명 표준\(DSS\) - 미국 국립 표준 기술 연구소\(National Institute of Standards and Technology\)에서 승인하고 미국에서 2000년 1월 발행한 NIST FIPS PUB 186-2 "디지털 서명 표준"에 정의된 디지털 서명 알고리즘을 포함한 디지털 서명에 대한 표준입니다. 상무부 \[DSS\]. 중요한 업데이트 \[DSS-3\]의 초안이 작성되어 2006년 3월에 게시되었습니다.
디지털 서명 - 디지털 서명은 공개 키 암호화와 단방향 해시 기능을 활용하여 인증할 수 있고 위조하거나 부인하기 어려운 데이터 서명을 생성합니다.
핸드셰이크 트랜잭션의 매개변수를 설정하는 클라이언트와 서버 간의 초기 협상입니다.
초기화 벡터\(IV\) - 블록 암호가 CBC 모드에서 사용되는 경우 초기화 벡터는 암호화 전에 첫 번째 일반 텍스트 블록과 배타적 OR로 연결됩니다.
메시지 인증 코드\(MAC\) - 메시지 인증 코드는 메시지와 일부 비밀 데이터에서 계산된 단방향 해시입니다. 비밀 데이터를 알지 못하면 위조하기가 어렵습니다. 그 목적은 메시지가 변경되었는지 감지하는 것입니다.
마스터 비밀 - 암호화 키, MAC 비밀 및 IV를 생성하는 데 사용되는 보안 비밀 데이터입니다.
MD5 - MD5 \[MD5\]는 임의로 긴 데이터 스트림을 고정된 크기\(16바이트\)의 해시로 변환하는 해싱 함수입니다. 암호 분석의 상당한 진전으로 인해 이 문서가 출판되는 시점에서 MD5는 더 이상 '보안' 해싱 기능으로 간주될 수 없습니다.
공개 키 암호화 - 두 개의 키 암호를 사용하는 암호화 기술의 한 종류입니다. 공개 키로 암호화된 메시지는 연결된 개인 키로만 해독할 수 있습니다. 반대로, 개인 키로 서명된 메시지는 공개 키로 확인할 수 있습니다.
단방향 해시 함수 - 임의의 양의 데이터를 고정 길이 해시로 변환하는 단방향 변환입니다. 변환을 되돌리거나 충돌을 찾는 것은 계산상 어렵습니다. MD5 및 SHA는 단방향 해시 함수의 예입니다.
RC4 - Ron Rivest가 발명한 스트림 암호입니다. 호환되는 암호는 \[SCH\]에 설명되어 있습니다.
RSA - 암호화 또는 디지털 서명에 사용할 수 있는 매우 널리 사용되는 공개 키 알고리즘입니다. \[RSA\]
서버 - 서버는 클라이언트의 연결 요청에 응답하는 애플리케이션 엔터티입니다. "클라이언트"도 참조하세요.
세션 - TLS 세션은 클라이언트와 서버 간의 연결입니다. 세션은 핸드셰이크 프로토콜에 의해 생성됩니다. 세션은 여러 연결에서 공유할 수 있는 암호화 보안 매개변수 세트를 정의합니다. 세션은 각 연결에 대한 새로운 보안 매개변수의 값비싼 협상을 피하기 위해 사용됩니다.
세션 식별자 - 세션 식별자는 특정 세션을 식별하는 서버에서 생성된 값입니다.
서버 쓰기 키 - 서버에서 쓴 데이터를 암호화하는 데 사용되는 키입니다.
서버 쓰기 MAC 키 - 서버에서 작성한 데이터를 인증하는 데 사용되는 비밀 데이터입니다.
SHA - 보안 해시 알고리즘\[SHS\]은 FIPS PUB 180-2에 정의되어 있습니다. 20바이트 출력을 생성합니다. 숫자 접미사 없이 SHA에 대한 모든 참조는 실제로 수정된 SHA-1 알고리즘을 사용합니다.
SHA-256 - 256비트 보안 해시 알고리즘은 FIPS PUB 180-2에 정의되어 있습니다. 32바이트 출력을 생성합니다.
SSL - Netscape의 보안 소켓 계층 프로토콜 \[SSL3\]. TLS는 SSL 버전 3.0을 기반으로 합니다.
스트림 암호\(stream cipher\) - 키를 암호학적으로 강력한 키스트림으로 변환한 다음 일반 텍스트와 배타적 OR로 연결하는 암호화 알고리즘입니다.
```text
symmetric cipher
See bulk cipher.
```
TLS\(전송 계층 보안\) - 이 프로토콜은 다음과 같습니다. 또한 IETF\(Internet Engineering Task Force\)의 전송 계층 보안 작업 그룹도 있습니다. 이 문서 끝에 있는 "작업 그룹 정보"를 참조하십시오\(99페이지 참조\).
---
# **Appendix C. Cipher Suite Definitions**
```text
Cipher Suite Key Cipher Mac
Exchange
TLS_NULL_WITH_NULL_NULL NULL NULL NULL
TLS_RSA_WITH_NULL_MD5 RSA NULL MD5
TLS_RSA_WITH_NULL_SHA RSA NULL SHA
TLS_RSA_WITH_NULL_SHA256 RSA NULL SHA256
TLS_RSA_WITH_RC4_128_MD5 RSA RC4_128 MD5
TLS_RSA_WITH_RC4_128_SHA RSA RC4_128 SHA
TLS_RSA_WITH_3DES_EDE_CBC_SHA RSA 3DES_EDE_CBC SHA
TLS_RSA_WITH_AES_128_CBC_SHA RSA AES_128_CBC SHA
TLS_RSA_WITH_AES_256_CBC_SHA RSA AES_256_CBC SHA
TLS_RSA_WITH_AES_128_CBC_SHA256 RSA AES_128_CBC SHA256
TLS_RSA_WITH_AES_256_CBC_SHA256 RSA AES_256_CBC SHA256
TLS_DH_DSS_WITH_3DES_EDE_CBC_SHA DH_DSS 3DES_EDE_CBC SHA
TLS_DH_RSA_WITH_3DES_EDE_CBC_SHA DH_RSA 3DES_EDE_CBC SHA
TLS_DHE_DSS_WITH_3DES_EDE_CBC_SHA DHE_DSS 3DES_EDE_CBC SHA
TLS_DHE_RSA_WITH_3DES_EDE_CBC_SHA DHE_RSA 3DES_EDE_CBC SHA
TLS_DH_anon_WITH_RC4_128_MD5 DH_anon RC4_128 MD5
TLS_DH_anon_WITH_3DES_EDE_CBC_SHA DH_anon 3DES_EDE_CBC SHA
TLS_DH_DSS_WITH_AES_128_CBC_SHA DH_DSS AES_128_CBC SHA
TLS_DH_RSA_WITH_AES_128_CBC_SHA DH_RSA AES_128_CBC SHA
TLS_DHE_DSS_WITH_AES_128_CBC_SHA DHE_DSS AES_128_CBC SHA
TLS_DHE_RSA_WITH_AES_128_CBC_SHA DHE_RSA AES_128_CBC SHA
TLS_DH_anon_WITH_AES_128_CBC_SHA DH_anon AES_128_CBC SHA
TLS_DH_DSS_WITH_AES_256_CBC_SHA DH_DSS AES_256_CBC SHA
TLS_DH_RSA_WITH_AES_256_CBC_SHA DH_RSA AES_256_CBC SHA
TLS_DHE_DSS_WITH_AES_256_CBC_SHA DHE_DSS AES_256_CBC SHA
TLS_DHE_RSA_WITH_AES_256_CBC_SHA DHE_RSA AES_256_CBC SHA
TLS_DH_anon_WITH_AES_256_CBC_SHA DH_anon AES_256_CBC SHA
TLS_DH_DSS_WITH_AES_128_CBC_SHA256 DH_DSS AES_128_CBC SHA256
TLS_DH_RSA_WITH_AES_128_CBC_SHA256 DH_RSA AES_128_CBC SHA256
TLS_DHE_DSS_WITH_AES_128_CBC_SHA256 DHE_DSS AES_128_CBC SHA256
TLS_DHE_RSA_WITH_AES_128_CBC_SHA256 DHE_RSA AES_128_CBC SHA256
TLS_DH_anon_WITH_AES_128_CBC_SHA256 DH_anon AES_128_CBC SHA256
TLS_DH_DSS_WITH_AES_256_CBC_SHA256 DH_DSS AES_256_CBC SHA256
TLS_DH_RSA_WITH_AES_256_CBC_SHA256 DH_RSA AES_256_CBC SHA256
TLS_DHE_DSS_WITH_AES_256_CBC_SHA256 DHE_DSS AES_256_CBC SHA256
TLS_DHE_RSA_WITH_AES_256_CBC_SHA256 DHE_RSA AES_256_CBC SHA256
TLS_DH_anon_WITH_AES_256_CBC_SHA256 DH_anon AES_256_CBC SHA256
```
```text
Key IV Block
Cipher Type Material Size Size
------------ ------ -------- ---- -----
NULL Stream 0 0 N/A
RC4_128 Stream 16 0 N/A
3DES_EDE_CBC Block 24 8 8
AES_128_CBC Block 16 16 16
AES_256_CBC Block 32 16 16
```
```text
MAC Algorithm mac_length mac_key_length
-------- ----------- ---------- --------------
NULL N/A 0 0
MD5 HMAC-MD5 16 16
SHA HMAC-SHA1 20 20
SHA256 HMAC-SHA256 32 32
```
유형 - 스트림 암호인지 CBC 모드에서 실행되는 블록 암호인지를 나타냅니다.
키 자료 - 쓰기 키를 생성하는 데 사용되는 key\_block의 바이트 수입니다.
IV 크기 - 초기화 벡터를 생성하는 데 필요한 데이터 양입니다. 스트림 암호의 경우 0입니다. 블록 암호의 블록 크기와 동일합니다\(SecurityParameters.record\_iv\_length와 동일\).
블록 크기 - 블록 암호가 하나의 청크에서 암호화하는 데이터의 양입니다. CBC 모드에서 실행되는 블록 암호는 블록 크기의 짝수 배수만 암호화할 수 있습니다.
---
# **Appendix D. Implementation Notes**
TLS 프로토콜은 흔히 발생하는 많은 보안 실수를 방지할 수 없습니다. 이 섹션에서는 구현자를 지원하기 위한 몇 가지 권장 사항을 제공합니다.
---
### **D.1. Random Number Generation and Seeding**
TLS에는 암호화된 보안 의사 난수 생성기\(PRNG\)가 필요합니다. PRNG를 설계하고 시드할 때는 주의를 기울여야 합니다. 보안 해시 작업\(특히 SHA-1\)을 기반으로 하는 PRNG는 허용되지만 난수 생성기 상태의 크기보다 더 많은 보안을 제공할 수는 없습니다.
생산되는 시드 자료의 양을 추정하려면 각 시드 바이트에 예측할 수 없는 정보의 비트 수를 추가하세요. 예를 들어, PC 호환 18.2Hz 타이머에서 가져온 키스트로크 타이밍 값은 카운터 값의 전체 크기가 16비트 이상이라도 각각 1 또는 2개의 보안 비트를 제공합니다. 따라서 128비트 PRNG를 시드하려면 약 100개의 타이머 값이 필요합니다.
\[RANDOM\]은 무작위 값 생성에 대한 지침을 제공합니다.
---
### **D.2. Certificates and Authentication**
구현에서는 인증서의 무결성을 확인할 책임이 있으며 일반적으로 인증서 해지 메시지를 지원해야 합니다. 인증서는 항상 신뢰할 수 있는 인증 기관\(CA\)의 올바른 서명을 확인해야 합니다. 신뢰할 수 있는 CA를 선택하고 추가하는 작업은 매우 신중하게 수행되어야 합니다. 사용자는 인증서 및 루트 CA에 대한 정보를 볼 수 있어야 합니다.
---
### **D.3. Cipher Suites**
TLS는 보안을 제공하지 않거나 최소한의 보안을 제공하는 것을 포함하여 다양한 키 크기와 보안 수준을 지원합니다. 적절한 구현은 아마도 많은 암호화 제품군을 지원하지 않을 것입니다. 예를 들어 익명의 Diffie-Hellman은 중간자 공격을 방지할 수 없으므로 사용하지 않는 것이 좋습니다. 또한 애플리케이션은 최소 및 최대 키 크기를 적용해야 합니다. 예를 들어, 512비트 RSA 키 또는 서명이 포함된 인증서 체인은 보안 수준이 높은 애플리케이션에 적합하지 않습니다.
---
### **D.4. Implementation Pitfalls**
구현 경험에 따르면 이전 TLS 사양의 특정 부분은 이해하기 쉽지 않으며 상호 운용성 및 보안 문제의 원인이 되어 왔습니다. 이들 지역 중 상당수는
이 문서에서 명확하게 설명되어 있지만 이 부록에는 구현자의 특별한 주의가 필요한 가장 중요한 사항에 대한 간단한 목록이 포함되어 있습니다.
```text
TLS protocol issues:
```
- 여러 TLS 레코드로 조각화된 핸드셰이크 메시지를 올바르게 처리합니까\(섹션 6.2.1 참조\)? 여러 개의 작은 조각으로 분할된 ClientHello와 같은 특수 사례를 포함합니까? 최대 조각 크기를 초과하는 핸드셰이크 메시지를 조각화합니까? 특히 인증서와 인증서 요청 핸드셰이크 메시지의 크기가 너무 커서 조각화가 필요할 수 있습니다.
- ServerHello 이전의 모든 TLS 레코드에서 TLS 레코드 계층 버전 번호를 무시합니까\(부록 E.1 참조\)?
- 확장 필드를 완전히 생략하는 것을 포함하여 ClientHello에서 TLS 확장을 올바르게 처리합니까?
- 클라이언트와 서버 모두에서 시작된 재협상을 지원합니까? 재협상은 선택적인 기능이지만 이를 지원하는 것이 좋습니다.
- 서버가 클라이언트 인증서를 요청했지만 적합한 인증서를 사용할 수 없는 경우 전체 메시지를 생략하는 대신 빈 인증서 메시지를 올바르게 보내나요\(섹션 7.4.6 참조\)?
```text
Cryptographic details:
```
- RSA로 암호화된 Premaster Secret에 버전번호가 정확하게 전송되고 검증되었나요? 오류가 발생하면 Bleichenbacher 공격을 피하기 위해 핸드셰이크를 계속합니까\(섹션 7.4.7.1 참조\)?
- RSA 복호화 및 서명 작업에 대한 타이밍 공격을 방지하기 위해 어떤 대책을 사용합니까\(섹션 7.4.7.1 참조\)?
- RSA 서명을 확인할 때 NULL 및 누락된 매개변수를 모두 허용합니까\(섹션 4.7 참조\)? RSA 패딩에 해시 값 뒤에 추가 데이터가 없는지 확인합니까? \[FI06\]
- Diffie-Hellman 키 교환을 사용할 때 협상된 키에서 선행 0바이트를 올바르게 제거합니까\(섹션 8.1.2 참조\)?
- TLS 클라이언트는 서버에서 보낸 Diffie-Hellman 매개변수가 허용되는지 확인합니까\(섹션 F.1.1.3 참조\)?
- CBC 모드 암호에 대해 예측할 수 없는 IV를 어떻게 생성합니까\(섹션 6.2.3.2 참조\)?
- 긴 CBC 모드 패딩\(최대 255바이트, 섹션 6.2.3.2 참조\)을 허용합니까?
```text
- How do you address CBC mode timing attacks (Section 6.2.3.2)?
```
- 프리마스터 비밀\(RSA 키 교환용\), Diffie-Hellman 개인 값, DSA "k" 매개변수 및 기타 생성을 위해 강력하고 가장 중요하게 적절하게 시드된 난수 생성기\(부록 D.1 참조\)를 사용합니까? 보안에 중요한 가치?
---
# **Appendix E. Backward Compatibility**
---
### **E.1. Compatibility with TLS 1.0/1.1 and SSL 3.0**
TLS\(1.0, 1.1, 1.2 및 향후 버전\)와 SSL\(2.0 및 3.0\)에는 다양한 버전이 있으므로 사용할 특정 프로토콜 버전을 협상하는 수단이 필요합니다. TLS 프로토콜은 버전 선택의 복잡성으로 인해 다른 프로토콜 구성 요소를 방해하지 않도록 버전 협상을 위한 내장 메커니즘을 제공합니다.
TLS 버전 1.0, 1.1, 1.2와 SSL 3.0은 매우 유사하며 호환되는 ClientHello 메시지를 사용합니다. 따라서 이들 모두를 지원하는 것은 상대적으로 쉽습니다. 마찬가지로 서버는 ClientHello 형식이 호환 가능하고 클라이언트가 서버에서 사용 가능한 가장 높은 프로토콜 버전을 지원하는 한 향후 버전의 TLS를 사용하려는 클라이언트를 쉽게 처리할 수 있습니다.
이러한 이전 서버와 협상하려는 TLS 1.2 클라이언트는 ClientHello.client\_version에 { 3, 3 }\(TLS 1.2\)이 포함된 일반 TLS 1.2 ClientHello를 보냅니다. 서버가 이 버전을 지원하지 않으면 이전 버전 번호가 포함된 ServerHello로 응답합니다. 클라이언트가 이 버전을 사용하는 데 동의하면 협상된 프로토콜에 맞게 협상이 진행됩니다.
서버가 선택한 버전이 클라이언트에서 지원되지 않는 경우\(또는 허용되지 않는 경우\) 클라이언트는 반드시 "protocol\_version" 경고 메시지를 보내고 연결을 닫아야 합니다.
TLS 서버가 서버가 지원하는 최고 버전보다 높은 버전 번호가 포함된 ClientHello를 수신하는 경우 서버가 지원하는 최고 버전에 따라 응답해야 합니다.
TLS 서버는 지원되는 가장 높은 버전보다 작은 버전 번호가 포함된 ClientHello를 수신할 수도 있습니다. 서버가 기존 클라이언트와 협상을 원하는 경우 적절하게 진행됩니다.
ClientHello.client\_version보다 크지 않은 서버에서 지원하는 가장 높은 버전의 경우. 예를 들어 서버가 TLS 1.0, 1.1 및 1.2를 지원하고 client\_version이 TLS 1.0인 경우 서버는 TLS 1.0 ServerHello를 진행합니다. 서버가 client\_version보다 높은 버전만 지원하거나 사용하려는 경우 "protocol\_version" 경고 메시지를 보내고 연결을 닫아야 합니다.
클라이언트가 서버에 알려진 가장 높은 프로토콜 버전을 이미 알고 있을 때마다\(예: 세션을 재개할 때\) 해당 기본 프로토콜에서 연결을 시작해야 합니다.
참고: 일부 서버 구현은 버전 협상을 잘못 구현하는 것으로 알려져 있습니다. 예를 들어, 클라이언트가 TLS 1.0보다 최신 버전을 제공할 때 단순히 연결을 닫는 버그가 있는 TLS 1.0 서버가 있습니다. 또한 ClientHello에 TLS 확장이 포함되어 있으면 일부 서버가 연결을 거부하는 것으로 알려져 있습니다. 이러한 버그가 있는 서버와의 상호 운용성은 이 문서의 범위를 벗어나는 복잡한 주제이며 클라이언트가 여러 번 연결을 시도해야 할 수도 있습니다.
TLS 사양의 이전 버전에서는 ClientHello를 보낼 때 레코드 계층 버전 번호\(TLSPlaintext.version\)에 어떤 내용이 포함되어야 하는지\(즉, 어떤 버전의 프로토콜이 사용될지 알기 전에\) 완전히 명확하지 않았습니다. 따라서 이 사양을 준수하는 TLS 서버는 ClientHello의 레코드 계층 버전 번호로 모든 값 {03,XX}를 허용해야 합니다.
이전 서버와 협상하려는 TLS 클라이언트는 레코드 레이어 버전 번호로 {03,XX} 값을 보낼 수 있습니다. 일반적인 값은 클라이언트가 지원하는 가장 낮은 버전 번호인 {03,00}과 ClientHello.client\_version 값입니다. 단일 값은 모든 기존 서버와의 상호 운용성을 보장하지 않지만 이는 이 문서의 범위를 벗어나는 복잡한 주제입니다.
---
### **E.2. Compatibility with SSL 2.0**
SSL 2.0 서버를 지원하려는 TLS 1.2 클라이언트는 \[SSL2\]에 정의된 버전 2.0 CLIENT-HELLO 메시지를 보내야 합니다. 메시지는 일반 ClientHello에 사용되는 것과 동일한 버전 번호를 포함해야 하며 아래 설명된 대로 CIPHER-SPECS-DATA 필드에 지원되는 TLS 암호화 제품군을 인코딩해야 합니다.
경고: 최신 ClientHello 형식이 최신 버전으로 이동하고 확장 협상을 위한 더 나은 메커니즘을 제공하므로 버전 2.0 CLIENT-HELLO 메시지를 보내는 기능은 서둘러 단계적으로 중단될 예정입니다. TLS 1.2 클라이언트는 SSL 2.0을 지원해서는 안 됩니다.
그러나 SSL 2.0을 지원하지 않는 TLS 서버라도 버전 2.0 CLIENT-HELLO 메시지를 받아들일 수 있습니다. 메시지는 TLS 서버 구현자를 위해 아래에 충분히 자세히 표시되어 있습니다. 실제 정의는 여전히 \[SSL2\]로 가정됩니다.
협상 목적을 위해 2.0 CLIENT-HELLO는 확장자가 없고 "null" 압축 방법을 사용하는 ClientHello와 동일한 방식으로 해석됩니다. 이 메시지는 TLS 레코드로 래핑되지 않고 유선으로 직접 전송되어야 합니다. Finished 및 CertificateVerify 계산을 위해 msg\_length 필드는 핸드셰이크 메시지의 일부로 간주되지 않습니다.
```text
uint8 V2CipherSpec[3];
struct {
uint16 msg_length;
uint8 msg_type;
Version version;
uint16 cipher_spec_length;
uint16 session_id_length;
uint16 challenge_length;
V2CipherSpec cipher_specs[V2ClientHello.cipher_spec_length];
opaque session_id[V2ClientHello.session_id_length];
opaque challenge[V2ClientHello.challenge_length;
} V2ClientHello;
```
msg\_length - 가장 높은 비트는 1이어야 합니다. 나머지 비트에는 다음 데이터의 길이\(바이트\)가 포함됩니다.
msg\_type - 이 필드는 버전 필드와 함께 버전 2 ClientHello 메시지를 식별합니다. 값은 1이어야 합니다.
버전 - ClientHello.client\_version과 동일합니다.
cipher\_spec\_length - 이 필드는 cipher\_specs 필드의 전체 길이입니다. 0일 수 없으며 V2CipherSpec 길이\(3\)의 배수여야 합니다.
session\_id\_length - 이 필드는 TLS 1.2를 지원한다고 주장하는 클라이언트에 대해 0 값을 가져야 합니다.
Challenge\_length - 클라이언트가 자신을 인증하기 위해 서버에 요청하는 길이\(바이트\)입니다. 역사적으로 허용되는 값은 16바이트에서 32바이트 사이입니다. SSLv2 이전 버전과 호환되는 핸드셰이크를 사용할 때 클라이언트는 32바이트 챌린지를 사용해야 합니다.
cipher\_specs - 클라이언트가 사용할 의향이 있고 사용할 수 있는 모든 CipherSpec의 목록입니다. \[SSL2\]에 정의된 2.0 암호화 사양 외에도 여기에는 일반적으로 ClientHello.cipher\_suites에서 전송되는 TLS 암호화 제품군이 포함되며, 각 암호화 제품군 앞에는 0바이트가 붙습니다. 예를 들어 TLS 암호 그룹 {0x00,0x0A}는 {0x00,0x00,0x0A}로 전송됩니다.
session\_id - 이 필드는 비어 있어야 합니다.
Challenge - ClientHello.random에 해당합니다. 챌린지 길이가 32보다 작은 경우 TLS 서버는 데이터를 32바이트 길이로 만들기 위해 선행\(참고: 후행 아님\) 0바이트로 데이터를 채웁니다.
참고: TLS 세션 재개 요청은 TLS 클라이언트 hello를 사용해야 합니다.
---
### **E.3. Avoiding Man-in-the-Middle Version Rollback**
TLS 클라이언트가 버전 2.0 호환 모드로 대체되면 특별한 PKCS#1 블록 형식을 사용해야 합니다. 이는 TLS 서버가 TLS 가능 클라이언트와의 버전 2.0 세션을 거부하도록 하기 위한 것입니다.
클라이언트가 SSL 2.0을 협상하지만 TLS도 지원하는 경우 ENCRYPTED-KEY의 RSA 암호화를 위해 PKCS 패딩의 오른쪽\(최하위\) 임의 바이트 8개\(패딩의 터미널 null은 포함하지 않음\)를 설정해야 합니다. CLIENT-MASTER-KEY의 DATA 필드는 0x03입니다\(다른 패딩 바이트는 무작위입니다\).
TLS 가능 서버가 SSL 2.0을 협상할 때 ENCRYPTED-KEY-DATA 필드를 해독한 후 이 8개의 패딩 바이트가 0x03인지 확인해야 합니다. 그렇지 않은 경우 서버는 SECRET-KEY-DATA에 대한 임의의 값을 생성하고 핸드셰이크를 계속해야 합니다\(키가 일치하지 않기 때문에 결국 실패하게 됩니다\). 오류 상황을 클라이언트에 보고하면 서버가 \[BLEI\]에 설명된 공격에 취약해질 수 있습니다.
---
# **Appendix F. Security Analysis**
TLS 프로토콜은 안전하지 않은 채널을 통해 통신하는 클라이언트와 서버 간에 보안 연결을 설정하도록 설계되었습니다. 이 문서에서는 공격자가 상당한 컴퓨팅 리소스를 보유하고 있으며 프로토콜 외부 소스로부터 비밀 정보를 얻을 수 없다는 점을 포함하여 몇 가지 전통적인 가정을 하고 있습니다. 공격자는 통신 채널을 통해 전송된 메시지를 캡처, 수정, 삭제, 재생 및 변조할 수 있는 능력을 갖고 있는 것으로 간주됩니다. 이 부록에서는 TLS가 다양한 공격에 저항하도록 어떻게 설계되었는지 간략하게 설명합니다.
---
### **F.1. Handshake Protocol**
핸드셰이크 프로토콜은 암호 사양을 선택하고 보안 세션과 관련된 기본 암호화 매개 변수를 함께 구성하는 마스터 비밀을 생성하는 역할을 합니다. 핸드셰이크 프로토콜은 선택적으로 신뢰할 수 있는 인증 기관에서 서명한 인증서를 가진 당사자를 인증할 수도 있습니다.
---
#### **F.1.1. Authentication and Key Exchange**
TLS는 양 당사자 인증, 인증되지 않은 클라이언트를 사용한 서버 인증, 전체 익명성이라는 세 가지 인증 모드를 지원합니다. 서버가 인증될 때마다 채널은 중간자 공격으로부터 안전하지만 완전히 익명인 세션은 본질적으로 이러한 공격에 취약합니다. 익명 서버는 클라이언트를 인증할 수 없습니다. 서버가 인증되면 해당 인증서 메시지는 허용되는 인증 기관으로 연결되는 유효한 인증서 체인을 제공해야 합니다. 마찬가지로 인증된 클라이언트는 서버에 허용 가능한 인증서를 제공해야 합니다. 각 당사자는 상대방의 인증서가 유효하고 만료되거나 취소되지 않았는지 확인할 책임이 있습니다.
키 교환 프로세스의 일반적인 목표는 공격자가 아닌 통신 당사자에게 알려진 pre\_master\_secret을 생성하는 것입니다. pre\_master\_secret은 master\_secret을 생성하는 데 사용됩니다\(섹션 8.1 참조\). 완료 메시지, 암호화 키 및 MAC 키를 생성하려면 master\_secret이 필요합니다\(섹션 7.4.9 및 6.3 참조\). 올바른 완료 메시지를 전송함으로써 당사자는 올바른 pre\_master\_secret을 알고 있음을 증명합니다.
---
##### **F.1.1.1. Anonymous Key Exchange**
키 교환을 위해 Diffie-Hellman을 사용하여 완전한 익명 세션을 설정할 수 있습니다. 서버의 공개 매개변수는 서버 키 교환 메시지에 포함되어 있으며 클라이언트의 공개 매개변수는
클라이언트 키 교환 메시지. 비공개 값을 모르는 도청자는 Diffie-Hellman 결과\(즉, pre\_master\_secret\)를 찾을 수 없어야 합니다.
경고: 완전한 익명 연결은 수동적 도청에 대한 보호만 제공합니다. Finished 메시지가 공격자에 의해 대체되지 않았는지 확인하기 위해 독립적인 변조 방지 채널을 사용하지 않는 한, 활성 중간자 공격이 우려되는 환경에서는 서버 인증이 필요합니다.
---
##### **F.1.1.2. RSA Key Exchange and Authentication**
RSA를 사용하면 키 교환과 서버 인증이 결합됩니다. 공개 키는 서버의 인증서에 포함되어 있습니다. 서버의 정적 RSA 키가 손상되면 해당 정적 키로 보호되는 모든 세션의 기밀성이 손실됩니다. Perfect Forward Secrecy를 원하는 TLS 사용자는 DHE 암호화 제품군을 사용해야 합니다. 개인 키\(및 인증서\)를 자주 변경하면 개인 키 노출로 인한 피해를 제한할 수 있습니다.
클라이언트는 서버의 인증서를 확인한 후 서버의 공개 키를 사용하여 pre\_master\_secret을 암호화합니다. pre\_master\_secret을 성공적으로 디코딩하고 올바른 Finished 메시지를 생성함으로써 서버는 서버 인증서에 해당하는 개인 키를 알고 있음을 보여줍니다.
RSA가 키 교환에 사용될 때 클라이언트는 인증서 확인 메시지를 사용하여 인증됩니다\(섹션 7.4.8 참조\). 클라이언트는 이전의 모든 핸드셰이크 메시지에서 파생된 값에 서명합니다. 이러한 핸드셰이크 메시지에는 서명을 서버에 바인딩하는 서버 인증서와 서명을 현재 핸드셰이크 프로세스에 바인딩하는 ServerHello.random이 포함됩니다.
---
##### **F.1.1.3. Diffie-Hellman Key Exchange with Authentication**
Diffie-Hellman 키 교환이 사용되는 경우 서버는 고정된 Diffie-Hellman 매개변수가 포함된 인증서를 제공하거나 서버 키 교환 메시지를 사용하여 DSA 또는 RSA 인증서로 서명된 임시 Diffie-Hellman 매개변수 세트를 보낼 수 있습니다. 공격자가 이전 매개변수를 재생하지 않도록 서명하기 전에 임시 매개변수가 hello.random 값으로 해시됩니다. 두 경우 모두 클라이언트는 인증서나 서명을 확인하여 매개변수가 서버에 속해 있는지 확인할 수 있습니다.
클라이언트에 고정된 Diffie-Hellman 매개변수가 포함된 인증서가 있는 경우 해당 인증서에는 키 교환을 완료하는 데 필요한 정보가 포함됩니다. 이 경우 클라이언트와 서버는 동일한 Diffie-Hellman 결과를 생성합니다\(예:
pre\_master\_secret\) 통신할 때마다. pre\_master\_secret이 필요 이상으로 메모리에 오래 머무르는 것을 방지하려면 최대한 빨리 master\_secret으로 변환해야 합니다. 키 교환이 작동하려면 클라이언트 Diffie-Hellman 매개변수가 서버에서 제공하는 매개변수와 호환되어야 합니다.
클라이언트에 표준 DSA 또는 RSA 인증서가 있거나 인증되지 않은 경우 클라이언트 키 교환 메시지에 포함된 임시 매개변수 세트를 서버에 보낸 다음 선택적으로 인증서 확인 메시지를 사용하여 자체 인증합니다.
클라이언트나 서버에 고정 DH 키 쌍이 포함된 인증서가 있거나 서버가 DH 키를 재사용하기 때문에 여러 핸드셰이크에 동일한 DH 키 쌍을 사용하는 경우 소규모 하위 그룹 공격을 방지하기 위해 주의를 기울여야 합니다. 구현은 \[SUBGROUP\]에 있는 지침을 따라야 합니다.
소규모 하위 그룹 공격은 DHE 암호화 제품군 중 하나를 사용하고 각 핸드셰이크에 대해 새로운 DH 개인 키\(X\)를 생성함으로써 가장 쉽게 피할 수 있습니다. 적절한 밑\(예: 2\)을 선택하면 g^X mod p를 매우 빠르게 계산할 수 있습니다. 따라서 성능 비용이 최소화됩니다. 또한 각 핸드셰이크에 새로운 키를 사용하면 완벽한 전달 보안이 제공됩니다. 구현에서는 DHE 암호화 제품군을 사용할 때 각 핸드셰이크에 대해 새로운 X를 생성해야 합니다\(SHOULD\).
TLS를 사용하면 서버가 임의의 DH 그룹을 제공할 수 있으므로 클라이언트는 DH 그룹이 로컬 정책에 정의된 대로 적절한 크기인지 확인해야 합니다. 클라이언트는 또한 DH 공개 지수가 적절한 크기인지 확인해야 합니다. \[KEYSIZ\]는 다양한 그룹 규모의 강점에 대한 유용한 가이드를 제공합니다. 서버는 \[IKEALG\] 또는 \[MODP\]에 정의된 것과 같은 알려진 그룹을 제공하여 클라이언트를 지원하도록 선택할 수 있습니다. 이는 간단한 비교를 통해 확인할 수 있습니다.
---
#### **F.1.2. Version Rollback Attacks**
TLS에는 SSL 버전 2.0에 비해 상당한 개선 사항이 포함되어 있으므로 공격자는 TLS 지원 클라이언트와 서버를 버전 2.0으로 대체하려고 시도할 수 있습니다. 이 공격은 두 개의 TLS 가능 당사자가 SSL 2.0 핸드셰이크를 사용하는 경우에만 발생할 수 있습니다.
무작위가 아닌 PKCS #1 블록 유형 2 메시지 패딩을 사용하는 솔루션은 우아하지 않지만 버전 3.0 서버가 공격을 탐지할 수 있는 합리적이고 안전한 방법을 제공합니다. 이 솔루션은 애플리케이션이 지정한 대기 임계값이 만료되기 전에 키를 무차별 대입하여 동일한 키\(그러나 일반 패딩 포함\)가 포함된 새 ENCRYPTED-KEY-DATA 메시지로 대체할 수 있는 공격자로부터 안전하지 않습니다. PKCS의 최하위 8바이트 패딩 변경
패딩은 서명된 해시 크기와 프로토콜에 사용되는 RSA 키 길이에 대한 보안에 영향을 미치지 않습니다. 이는 본질적으로 입력 블록 크기를 8바이트 늘리는 것과 동일하기 때문입니다.
---
#### **F.1.3. Detecting Attacks Against the Handshake Protocol**
공격자는 당사자가 일반적으로 선택하는 것과 다른 암호화 알고리즘을 선택하도록 핸드셰이크 교환에 영향을 주려고 시도할 수 있습니다.
이 공격의 경우 공격자는 하나 이상의 핸드셰이크 메시지를 적극적으로 변경해야 합니다. 이런 일이 발생하면 클라이언트와 서버는 핸드셰이크 메시지 해시에 대해 서로 다른 값을 계산합니다. 결과적으로 당사자들은 서로의 완료 메시지를 수락하지 않습니다. master\_secret이 없으면 공격자는 Finished 메시지를 복구할 수 없으므로 공격이 발견됩니다.
---
#### **F.1.4. Resuming Sessions**
세션을 재개하여 연결이 설정되면 새 ClientHello.random 및 ServerHello.random 값이 세션의 master\_secret으로 해시됩니다. master\_secret이 손상되지 않았고 암호화 키와 MAC 키를 생성하는 데 사용된 보안 해시 작업이 안전하다면 연결은 안전해야 하며 이전 연결과 효과적으로 독립적이어야 합니다. 공격자는 알려진 암호화 키나 MAC 비밀을 사용하여 보안 해시 작업을 중단하지 않고 master\_secret을 손상시킬 수 없습니다.
클라이언트와 서버가 모두 동의하지 않으면 세션을 재개할 수 없습니다. 세션이 손상되었거나 인증서가 만료 또는 취소되었을 수 있다고 의심되는 경우 당사자는 전체 핸드셰이크를 강제해야 합니다. master\_secret을 획득한 공격자가 해당 세션 ID가 만료될 때까지 손상된 당사자를 가장할 수 있으므로 세션 ID 수명에 대해 24시간의 상한이 제안됩니다. 상대적으로 안전하지 않은 환경에서 실행될 수 있는 애플리케이션은 안정적인 저장소에 세션 ID를 기록해서는 안 됩니다.
---
### **F.2. Protecting Application Data**
master\_secret은 ClientHello.random 및 ServerHello.random으로 해시되어 각 연결에 대한 고유한 데이터 암호화 키와 MAC 비밀을 생성합니다.
나가는 데이터는 전송 전에 MAC으로 보호됩니다. 메시지 재생이나 수정 공격을 방지하기 위해 MAC는 MAC 키, 시퀀스 번호, 메시지 길이,
메시지 내용과 두 개의 고정 문자열. 하나의 TLS 레코드 계층 클라이언트를 대상으로 하는 메시지가 다른 TLS 레코드 계층 클라이언트로 리디렉션되지 않도록 하려면 메시지 유형 필드가 필요합니다. 시퀀스 번호는 메시지를 삭제하거나 재정렬하려는 시도가 감지되도록 보장합니다. 시퀀스 번호는 64비트 길이이므로 절대로 오버플로되어서는 안 됩니다. 한 당사자의 메시지는 독립적인 MAC 키를 사용하므로 다른 당사자의 출력에 삽입될 수 없습니다. 마찬가지로 서버 쓰기 키와 클라이언트 쓰기 키는 독립적이므로 스트림 암호화 키는 한 번만 사용됩니다.
공격자가 암호화 키를 해독하면 해당 키로 암호화된 모든 메시지를 읽을 수 있습니다. 마찬가지로 MAC 키가 손상되면 메시지 수정 공격이 가능해집니다. MAC도 암호화되기 때문에 메시지 변경 공격을 위해서는 일반적으로 MAC뿐만 아니라 암호화 알고리즘도 깨뜨려야 합니다.
참고: MAC 키는 암호화 키보다 클 수 있으므로 암호화 키가 손상되더라도 메시지는 변조 방지 상태를 유지할 수 있습니다.
---
### **F.3. Explicit IVs**
\[CBCATT\]는 레코드에 대한 IV를 아는 데 의존하는 TLS에 대한 선택된 일반 텍스트 공격을 설명합니다. 이전 버전의 TLS\[TLS1.0\]는 이전 레코드의 CBC 잔여물을 IV로 사용했기 때문에 이 공격이 가능했습니다. 이 버전은 이 공격으로부터 보호하기 위해 명시적인 IV를 사용합니다.
---
### **F.4. Security of Composite Cipher Modes**
TLS는 협상된 암호화 제품군에 정의된 대칭 암호화 및 인증 기능을 사용하여 전송된 애플리케이션 데이터를 보호합니다. 목표는 네트워크에서 활동하는 공격자의 악의적인 행동으로부터 전송된 데이터의 무결성과 기밀성을 모두 보호하는 것입니다. 이러한 목표를 달성하기 위해서는 데이터에 암호화 및 인증 기능이 적용되는 순서가 중요한 역할을 하는 것으로 나타났다\[ENCAUTH\].
암호화 후 인증이라는 가장 강력한 방법은 먼저 데이터에 암호화를 적용한 다음 암호문에 MAC를 적용합니다. 이 방법은 전자가 선택된 일반 텍스트 공격에 대해 안전하고 MAC이 선택된 메시지 공격에 대해 안전하다는 전제 하에 모든 암호화 및 MAC 기능 쌍을 사용하여 무결성 및 기밀성 목표를 달성하도록 보장합니다. TLS는 인증 후 암호화라는 또 다른 방법을 사용합니다. 이 방법에서는 먼저 일반 텍스트에서 MAC을 계산한 다음 일반 텍스트와 MAC의 연결을 암호화합니다. 이 방법은 암호화 기능과 MAC 기능의 특정 조합에 대해 안전한 것으로 입증되었지만 일반적으로 안전하다고 보장할 수는 없습니다.
특히, 보안 MAC 기능과 결합된 완벽하게 안전한 암호화 기능\(정보이론적 의미에서도 보안\)이 존재하지만 적극적 공격에 대한 기밀성 목표를 제공하지 못하는 것으로 나타났습니다. 따라서 TLS에 채택된 새로운 암호화 제품군 및 작동 모드는 명시된 무결성 및 기밀성 목표를 달성하는지 확인하기 위해 인증 후 암호화 방법으로 분석되어야 합니다.
현재 인증 후 암호화 방식의 보안은 몇 가지 중요한 사례에서 입증되었습니다. 하나는 의사 난수 생성기를 사용하여 메시지 길이와 MAC 태그 길이를 더한 계산적으로 예측할 수 없는 패드가 생성되고 이 패드가 일반 텍스트와 MAC 태그의 연결과 배타적 OR로 연결되는 스트림 암호의 경우입니다. 다른 하나는 보안 블록 암호를 사용하는 CBC 모드의 경우입니다. 이 경우 일반 텍스트와 MAC의 연결에 하나의 CBC 암호화 패스를 적용하고 각각의 새로운 일반 텍스트와 MAC 쌍에 대해 새롭고 독립적이며 예측할 수 없는 IV를 사용하면 보안이 표시될 수 있습니다. TLS 1.1 이전 버전에서는 이전 암호문의 마지막 블록 형태로 예측 가능한 IV를 사용한 점을 제외하고는 CBC 모드가 올바르게 사용되었습니다. 이로 인해 TLS는 선택된 일반 텍스트 공격에 개방되었습니다. 이 버전의 프로토콜은 이러한 공격에 면역입니다. 안전한 것으로 입증된 암호화 모드에 대한 자세한 내용은 \[ENCAUTH\]를 참조하세요.
---
### **F.5. Denial of Service**
TLS는 다양한 DoS\(서비스 거부\) 공격에 취약합니다. 특히, 다수의 TCP 연결을 시작하는 공격자는 서버가 RSA 암호 해독을 수행하기 위해 많은 양의 CPU를 소비하게 만들 수 있습니다. 그러나 TLS는 일반적으로 TCP를 통해 사용되기 때문에 TCP 스택에서 적절한 TCP SYN 무작위화 \[SEQNUM\]를 사용하면 공격자가 자신의 원점을 숨기기가 어렵습니다.
TLS는 TCP를 통해 실행되기 때문에 개별 연결에 대한 여러 DoS 공격에도 취약합니다. 특히 공격자는 RST를 위조하여 연결을 종료하거나 부분 TLS 레코드를 위조하여 연결을 중단시킬 수 있습니다. 이러한 공격은 일반적으로 TCP 사용 프로토콜로 방어할 수 없습니다. 이 유형의 공격에 관심이 있는 구현자 또는 사용자는 IPsec AH\[AH\] 또는 ESP\[ESP\]를 사용해야 합니다.
---
### **F.6. Final Notes**
TLS가 보안 연결을 제공하려면 클라이언트와 서버 시스템, 키 및 애플리케이션이 모두 안전해야 합니다. 또한 구현에는 보안 오류가 없어야 합니다.
시스템은 가장 약한 키 교환 및 인증 알고리즘이 지원되는 만큼만 강력하며 신뢰할 수 있는 암호화 기능만 사용해야 합니다. 짧은 공개 키와 익명 서버는 매우 주의해서 사용해야 합니다. 구현과 사용자는 어떤 인증서와 인증 기관이 허용되는지 결정할 때 주의해야 합니다. 부정직한 인증 기관은 엄청난 피해를 입힐 수 있습니다.
---
# **Normative References**
```text
[AES] National Institute of Standards and Technology,
"Specification for the Advanced Encryption Standard (AES)"
FIPS 197. November 26, 2001.
[3DES] National Institute of Standards and Technology,
"Recommendation for the Triple Data Encryption Algorithm
(TDEA) Block Cipher", NIST Special Publication 800-67, May
2004.
[DSS] NIST FIPS PUB 186-2, "Digital Signature Standard",
National Institute of Standards and Technology, U.S.
Department of Commerce, 2000.
[HMAC] Krawczyk, H., Bellare, M., and R. Canetti, "HMAC: Keyed-
Hashing for Message Authentication", RFC 2104, February
1997.
[MD5] Rivest, R., "The MD5 Message-Digest Algorithm", RFC 1321,
April 1992.
[PKCS1] Jonsson, J. and B. Kaliski, "Public-Key Cryptography
Standards (PKCS) #1: RSA Cryptography Specifications
Version 2.1", RFC 3447, February 2003.
[PKIX] Housley, R., Polk, W., Ford, W., and D. Solo, "Internet
X.509 Public Key Infrastructure Certificate and
Certificate Revocation List (CRL) Profile", RFC 3280,
April 2002.
[SCH] B. Schneier. "Applied Cryptography: Protocols, Algorithms,
and Source Code in C, 2nd ed.", Published by John Wiley &
Sons, Inc. 1996.
[SHS] NIST FIPS PUB 180-2, "Secure Hash Standard", National
Institute of Standards and Technology, U.S. Department of
Commerce, August 2002.
[REQ] Bradner, S., "Key words for use in RFCs to Indicate
Requirement Levels", BCP 14, RFC 2119, March 1997.
[RFC2434] Narten, T. and H. Alvestrand, "Guidelines for Writing an
IANA Considerations Section in RFCs", BCP 26, RFC 2434,
October 1998.
[X680] ITU-T Recommendation X.680 (2002) | ISO/IEC 8824-1:2002,
Information technology - Abstract Syntax Notation One
(ASN.1): Specification of basic notation.
[X690] ITU-T Recommendation X.690 (2002) | ISO/IEC 8825-1:2002,
Information technology - ASN.1 encoding Rules:
Specification of Basic Encoding Rules (BER), Canonical
Encoding Rules (CER) and Distinguished Encoding Rules
(DER).
```
---
# **Informative References**
```text
[AEAD] McGrew, D., "An Interface and Algorithms for Authenticated
Encryption", RFC 5116, January 2008.
[AH] Kent, S., "IP Authentication Header", RFC 4302, December
2005.
[BLEI] Bleichenbacher D., "Chosen Ciphertext Attacks against
Protocols Based on RSA Encryption Standard PKCS #1" in
Advances in Cryptology -- CRYPTO'98, LNCS vol. 1462,
pages: 1-12, 1998.
[CBCATT] Moeller, B., "Security of CBC Ciphersuites in SSL/TLS:
Problems and Countermeasures",
http://www.openssl.org/~bodo/tls-cbc.txt.
[CBCTIME] Canvel, B., Hiltgen, A., Vaudenay, S., and M. Vuagnoux,
"Password Interception in a SSL/TLS Channel", Advances in
Cryptology -- CRYPTO 2003, LNCS vol. 2729, 2003.
[CCM] "NIST Special Publication 800-38C: The CCM Mode for
Authentication and Confidentiality",
http://csrc.nist.gov/publications/nistpubs/800-38C/
SP800-38C.pdf
[DES] National Institute of Standards and Technology, "Data
Encryption Standard (DES)", FIPS PUB 46-3, October 1999.
[DSS-3] NIST FIPS PUB 186-3 Draft, "Digital Signature Standard",
National Institute of Standards and Technology, U.S.
Department of Commerce, 2006.
[ECDSA] American National Standards Institute, "Public Key
Cryptography for the Financial Services Industry: The
Elliptic Curve Digital Signature Algorithm (ECDSA)", ANS
X9.62-2005, November 2005.
[ENCAUTH] Krawczyk, H., "The Order of Encryption and Authentication
for Protecting Communications (Or: How Secure is SSL?)",
Crypto 2001.
[ESP] Kent, S., "IP Encapsulating Security Payload (ESP)", RFC
4303, December 2005.
[FI06] Hal Finney, "Bleichenbacher's RSA signature forgery based
on implementation error", ietf-openpgp@imc.org mailing
list, 27 August 2006, http://www.imc.org/ietf-openpgp/
mail-archive/msg14307.html.
[GCM] Dworkin, M., NIST Special Publication 800-38D,
"Recommendation for Block Cipher Modes of Operation:
Galois/Counter Mode (GCM) and GMAC", November 2007.
[IKEALG] Schiller, J., "Cryptographic Algorithms for Use in the
Internet Key Exchange Version 2 (IKEv2)", RFC 4307,
December 2005.
[KEYSIZ] Orman, H. and P. Hoffman, "Determining Strengths For
Public Keys Used For Exchanging Symmetric Keys", BCP 86,
RFC 3766, April 2004.
[KPR03] Klima, V., Pokorny, O., Rosa, T., "Attacking RSA-based
Sessions in SSL/TLS", http://eprint.iacr.org/2003/052/,
March 2003.
[MODP] Kivinen, T. and M. Kojo, "More Modular Exponential (MODP)
Diffie-Hellman groups for Internet Key Exchange (IKE)",
RFC 3526, May 2003.
[PKCS6] RSA Laboratories, "PKCS #6: RSA Extended Certificate
Syntax Standard", version 1.5, November 1993.
[PKCS7] RSA Laboratories, "PKCS #7: RSA Cryptographic Message
Syntax Standard", version 1.5, November 1993.
[RANDOM] Eastlake, D., 3rd, Schiller, J., and S. Crocker,
"Randomness Requirements for Security", BCP 106, RFC 4086,
June 2005.
[RFC3749] Hollenbeck, S., "Transport Layer Security Protocol
Compression Methods", RFC 3749, May 2004.
[RFC4366] Blake-Wilson, S., Nystrom, M., Hopwood, D., Mikkelsen, J.,
and T. Wright, "Transport Layer Security (TLS)
Extensions", RFC 4366, April 2006.
[RSA] R. Rivest, A. Shamir, and L. M. Adleman, "A Method for
Obtaining Digital Signatures and Public-Key
Cryptosystems", Communications of the ACM, v. 21, n. 2,
Feb 1978, pp. 120-126.
[SEQNUM] Bellovin, S., "Defending Against Sequence Number Attacks",
RFC 1948, May 1996.
[SSL2] Hickman, Kipp, "The SSL Protocol", Netscape Communications
Corp., Feb 9, 1995.
[SSL3] A. Freier, P. Karlton, and P. Kocher, "The SSL 3.0
Protocol", Netscape Communications Corp., Nov 18, 1996.
[SUBGROUP] Zuccherato, R., "Methods for Avoiding the "Small-Subgroup"
Attacks on the Diffie-Hellman Key Agreement Method for
S/MIME", RFC 2785, March 2000.
[TCP] Postel, J., "Transmission Control Protocol", STD 7, RFC
793, September 1981.
[TIMING] Boneh, D., Brumley, D., "Remote timing attacks are
practical", USENIX Security Symposium 2003.
[TLSAES] Chown, P., "Advanced Encryption Standard (AES)
Ciphersuites for Transport Layer Security (TLS)", RFC
3268, June 2002.
[TLSECC] Blake-Wilson, S., Bolyard, N., Gupta, V., Hawk, C., and B.
Moeller, "Elliptic Curve Cryptography (ECC) Cipher Suites
for Transport Layer Security (TLS)", RFC 4492, May 2006.
[TLSEXT] Eastlake, D., 3rd, "Transport Layer Security (TLS)
Extensions: Extension Definitions", Work in Progress,
February 2008.
[TLSPGP] Mavrogiannopoulos, N., "Using OpenPGP Keys for Transport
Layer Security (TLS) Authentication", RFC 5081, November
2007.
[TLSPSK] Eronen, P., Ed., and H. Tschofenig, Ed., "Pre-Shared Key
Ciphersuites for Transport Layer Security (TLS)", RFC
4279, December 2005.
[TLS1.0] Dierks, T. and C. Allen, "The TLS Protocol Version 1.0",
RFC 2246, January 1999.
[TLS1.1] Dierks, T. and E. Rescorla, "The Transport Layer Security
(TLS) Protocol Version 1.1", RFC 4346, April 2006.
[X501] ITU-T Recommendation X.501: Information Technology - Open
Systems Interconnection - The Directory: Models, 1993.
[XDR] Eisler, M., Ed., "XDR: External Data Representation
Standard", STD 67, RFC 4506, May 2006.
```
---
# **Working Group Information**
IETF TLS 작업 그룹의 토론 목록은 전자 메일 주소 <tls@ietf.org\>에 있습니다. 그룹에 대한 정보와 목록 구독 방법에 대한 정보는 <https://www1.ietf.org/mailman/listinfo/tls\>에서 확인할 수 있습니다.
목록의 아카이브는 <http://www.ietf.org/mail-archive/web/tls/current/index.html\>에서 찾을 수 있습니다.
---
# **Contributors**
Christopher Allen\(TLS 1.0 공동 편집자\) Alacrity Ventures ChristopherA@AlacrityManagement.com
마틴 아바디 캘리포니아 대학교, 산타 크루즈 abadi@cs.ucsc.edu
```text
Steven M. Bellovin
Columbia University
smb@cs.columbia.edu
Simon Blake-Wilson
BCI
sblakewilson@bcisse.com
Ran Canetti
IBM
canetti@watson.ibm.com
Pete Chown
Skygate Technology Ltd
pc@skygate.co.uk
Taher Elgamal
taher@securify.com
Securify
Pasi Eronen
pasi.eronen@nokia.com
Nokia
Anil Gangolli
anil@busybuddha.org
Kipp Hickman
Alfred Hoenes
David Hopwood
Independent Consultant
david.hopwood@blueyonder.co.uk
```
Phil Karlton\(SSLv3 공동 저자\)
Paul Kocher\(SSLv3 공동 저자\) 암호화 연구 paul@cryptography.com
```text
Hugo Krawczyk
IBM
hugo@ee.technion.ac.il
Jan Mikkelsen
Transactionware
janm@transactionware.com
Magnus Nystrom
RSA Security
magnus@rsasecurity.com
Robert Relyea
Netscape Communications
relyea@netscape.com
Jim Roskind
Netscape Communications
jar@netscape.com
Michael Sabin
Dan Simon
Microsoft, Inc.
dansimon@microsoft.com
Tom Weinstein
Tim Wright
Vodafone
timothy.wright@vodafone.com
```
---
# **Editors' Addresses**
```text
Tim Dierks
Independent
EMail: tim@dierks.org
Eric Rescorla
RTFM, Inc.
EMail: ekr@rtfm.com
```
---
# **Full Copyright Statement**
저작권\(C\) IETF 트러스트\(2008\).
이 문서에는 BCP 78에 포함된 권리, 라이선스 및 제한 사항이 적용되며, 여기에 명시된 경우를 제외하고 작성자는 모든 권리를 보유합니다.
이 문서와 여기에 포함된 정보는 "있는 그대로" 제공되며 기여자, 그가 대표하거나 후원하는 조직\(있는 경우\), 인터넷 사회, IETF 트러스트 및 인터넷 엔지니어링 태스크 포스는 모든 것을 부인합니다. 여기에 있는 정보의 사용이 상품성이나 특정 목적에의 적합성에 대한 묵시적인 보증이나 권리를 침해하지 않는다는 보증을 포함하되 이에 국한되지 않는 명시적 또는 묵시적 보증.
---
# **Intellectual Property**
IETF는 이 문서에 설명된 기술의 구현이나 사용과 관련이 있다고 주장될 수 있는 지적 재산권 또는 기타 권리의 유효성이나 범위, 그러한 권리에 따른 라이선스가 적용되거나 적용되지 않을 수 있는 범위에 대해 어떠한 입장도 취하지 않습니다. 는 가능하다; 또한 그러한 권리를 확인하기 위해 독립적인 노력을 했다는 것을 나타내지도 않습니다. RFC 문서의 권리와 관련된 절차에 대한 정보는 BCP 78 및 BCP 79에서 확인할 수 있습니다.
IETF 사무국에 제출된 IPR 공개 사본 및 사용 가능한 라이센스에 대한 보증, 또는 이 사양의 구현자 또는 사용자가 해당 독점적 권리 사용에 대한 일반 라이센스 또는 허가를 얻으려는 시도의 결과를 얻을 수 있습니다. IETF 온라인 IPR 저장소\(http://www.ietf.org/ipr\)에서.
IETF는 이 표준을 구현하는 데 필요할 수 있는 기술에 적용될 수 있는 모든 저작권, 특허, 특허 출원 또는 기타 독점권에 관심을 갖도록 관심 있는 당사자를 초대합니다. IETF\(ietf-ipr@ietf.org\)에 해당 정보를 보내주십시오.
original document link : https://www.ietf.org/rfc/rfc5246.txt
Disclaimer of Accuracy for Translation:
This document is a translation of the original (RFC 5246). While every effort has been made to ensure the accuracy of this translation, it may contain errors or discrepancies. For verification of the content and to ensure consistency with the original document, please refer to the original version.
Non-Commercial Use and Educational Purpose Statement:
This translated document is intended solely for educational purposes and is not to be used for any commercial purposes. The content of this translation is provided to facilitate learning and understanding of the original (RFC 5246) and should not be utilized in any commercial context.
translator : yevgeny hong, used google translator api
contact : hongyevgeny@gmail.com