TLS握手以及协议详解
TLS
传输层安全 (Transport Layer Security) 对通过 Internet 发送的数据进行加密,以确保窃听者和黑客无法看到您传输的内容,这对于密码、信用卡号和个人通信等私人和敏感信息特别有用。本章解释了 TLS 是什么、它是如何工作的以及为什么要部署它。
未受保护的数据由应用层提供给TLS
- TLS处理加密(用于发送)、解密(用于接收)和完整性检查
- TLS将受保护的数据提供给传输层
- TLS设计为在TCP之上运行
- 但也可以通过UDP实现
Datagram Transport Layer Security (DTLS)
TLS 是一种加密协议,可为通过 Internet 在应用程序之间发送的数据提供端到端的安全性。用户最熟悉的是它在安全网络浏览中的使用,尤其是在建立安全会话时出现在网络浏览器中的挂锁图标。但是,它也可以而且确实应该用于其他应用程序,例如电子邮件、文件传输、视频/音频会议、即时消息和 IP 语音,以及 DNS 和 NTP 等 Internet 服务。
TLS握手
TLS握手和SSL握手
SSL 或 Secure Sockets Layer是为HTTP开发的原始安全协议。不久前,SSL 被 TLS 或传输层安全性取代。SSL 握手现在称为 TLS 握手,尽管“SSL”名称仍在广泛使用。
什么时候发生TLS握手
每当用户通过 HTTPS 导航到网站并且浏览器首先开始查询网站的源服务器时,就会发生 TLS 握手。每当任何其他通信使用 HTTPS(包括API 调用和基于 HTTPS 的 DNS查询)时,也会发生 TLS 握手。
TLS 握手发生在通过 TCP 握手打开TCP连接之后。
TLS握手步骤
TLS 握手是由客户端和服务器交换的一系列数据报或消息。TLS 握手涉及多个步骤,因为客户端和服务器交换完成握手所需的信息并使进一步的对话成为可能。
TLS 握手中的确切步骤将根据所使用的密钥交换算法的种类和双方支持的密码套件而有所不同。RSA 密钥交换算法虽然现在被认为不安全,但在 1.3 之前的 TLS 版本中使用。大致如下:
- 'client hello' 消息:客户端通过向服务器发送“hello”消息来启动握手。该消息将包括客户端支持的 TLS 版本、支持的密码套件以及称为“客户端随机”的随机字节串。
- “Server hello”消息:作为对客户端问候消息的回复,服务器发送一条消息,其中包含服务器的SSL 证书、服务器选择的密码套件和“服务器随机”,即服务器生成的另一个随机字节串。
- 身份验证:客户端使用颁发它的证书颁发机构验证服务器的 SSL 证书。这确认了服务器就是它所说的那个人,并且客户端正在与域的实际所有者进行交互。
- premaster secret:客户端再发送一个随机字节串,即“premaster secret”。premaster secret 是用公钥加密的,只能由服务器用私钥解密。(客户端从服务器的 SSL 证书中获取公钥。)
- 使用的私钥:服务器解密预主密钥。
- 创建会话密钥:客户端和服务器都从客户端随机、服务器随机和预主密钥生成会话密钥。他们应该得到相同的结果。
- 客户端已准备就绪:客户端发送一条使用会话密钥加密的“已完成”消息。
- 服务器准备就绪:服务器发送使用会话密钥加密的“已完成”消息。
- 实现安全对称加密:握手完成,使用会话密钥继续通信。
协议说明
较低层堆叠在TCP之上,因为它是面向连接且可靠的传输层协议。这一层基本上由TLS 记录协议组成。简而言之,记录协议首先将高层协议数据分片成 214 字节或更小的块;然后可选地压缩数据,添加消息验证码,最后根据密码规范(协商时)加密数据,添加 SSL 记录头。需要注意的一点是,每个块都被打包到一个不保留客户端消息边界的结构中,这意味着同一类型的多个消息可以合并到一个结构中。
下图描述了构建 SSL 记录的过程。
较高层堆叠在SSL记录协议之上,包含四个子协议。这些协议中的每一个都有一个非常特定的目的,并在通信的不同阶段使用:
-
握手协议:它允许对等方相互验证并协商密码套件和连接的其他参数。SSL 握手协议涉及在客户端和服务器之间交换的四组消息(有时称为航班)。每组通常在单独的 TCP 段中传输。下图显示了该过程的摘要,其中包含多个步骤并提供可选步骤。请注意,ChangeCipherSpec消息不属于该协议,因为它们本身就是一个协议,如下所示。
-
ChangeCipherSpec Protocol:它使之前协商的参数生效,因此通信变得加密。
-
警报协议:用于传达异常并指示可能危及安全的潜在问题。
-
应用数据协议:它获取任意数据(通常是应用层数据),并通过安全通道提供给它。
多个消息可以连接成一个记录层消息,但这些消息必须属于同一个子协议。因此,这四个协议中的每一个都必须是自定界的(即必须包括其自己的长度字段)。
这里主要讲一下握手协议
这是 TLS 中最复杂的子协议。该规范主要关注这一点,因为它处理建立安全连接所需的所有机制。下图显示了握手协议消息的一般结构。TLS 规范中有 10 种握手消息类型(不包括扩展),因此下面将分别介绍每种的具体格式。
-
HelloRequest:允许服务器重新启动握手协商。不经常使用。如果一个连接已经建立了足够长的时间,它的安全性被削弱了(以小时为单位),服务器可以使用这个消息来强制客户端重新协商新的会话密钥。
| | | | Handshake Layer | | - ---+----+----+----+----+ | | | | | 4 | 0 | 0 | 0 | 0 | - ---+----+----+----+----+ / | \ \---------\ / \\ record \ length: 0 length\ type: 0
-
ClientHello:此消息通常开始 TLS 握手协商。它与客户端支持的密码套件列表一起发送,以便服务器选择最适合的密码套件(最好是最强的)、压缩方法列表和扩展列表。通过包含SessionId字段,它还为客户端提供了重新启动先前会话的可能性。
| | | | Handshake Layer | | - ---+----+----+----+----+----+----+------+----+----------+--------+-----------+----------+ | 1 | | | | | |32-bit| |max 32-bit| Cipher |Compression|Extensions| |0x01| | | | 3 | 1 |random| |session Id| Suites | methods | | - ---+----+----+----+----+----+----+------+----+----------+--------+-----------+----------+ / | \ \---------\ \----\ \\ / \ \ \ \ SessionId record \ length SSL/TLS\ length \ version SessionId type: 1 (TLS 1.0 here) length CipherSuites +----+----+----+----+----+----+ | | | | | | | | | | | | | | +----+----+----+----+----+----+ \-----\ \-----\ \----\ \ \\ length cipher Id cipherId Compression methods (no practical implementation uses compression) +----+----+----+ | | | | | 0 | 1 | 0 | +----+----+----+ \-----\\ \\ length: 1 cmp Id: 0 Extensions +----+----+----+----+----+----+----- - - | | | | | | | | | | | | | |...extension data +----+----+----+----+----+----+----- - - \-----\ \-----\ \----\ \ \\ length Extension Extension data Id length
-
ServerHello:ServerHello 消息与 ClientHello 消息非常相似,不同之处在于它只包含一个 CipherSuite 和一个 Compression 方法。如果它包含一个 SessionId(即 SessionId 长度 > 0),它会向客户端发出信号以在将来尝试重用它。
| | | Handshake Layer | | - ---+----+----+----+----+----+----+----------+----+----------+----+----+----+----------+ | 2 | | | | | | 32byte | |max 32byte| | | |Extensions| |0x02| | | | 3 | 1 | random | |session Id| | | | | - ---+----+----+----+----+----+----+----------+----+----------+--------------+----------+ / | \ \---------\ \----\ \ \ \----\\ / \ \ \ \ SessionId \ Compression record \ length SSL/TLS \ (if length > 0) \ method length \ version SessionId\ type: 2 (TLS 1.0 here) length CipherSuite
-
证书:此消息的正文包含一个公钥证书链。证书链允许 TLS 支持证书层次结构和 PKI(公钥基础设施)。
| | | | Handshake Layer | | - ---+----+----+----+----+----+----+----+----+----+----+-----------+---- - - | 11 | | | | | | | | | | | |0x0b| | | | | | | | | |certificate| ...more certificate - ---+----+----+----+----+----+----+----+----+----+----+-----------+---- - - / | \ \---------\ \---------\ \---------\ / \ \ \\ record \ length Certificate Certificate length \ chain length type: 11 length
-
ServerKeyExchange:此消息携带客户端需要从服务器获得的密钥交换算法参数,以便之后对称加密工作。它是可选的,因为并非所有密钥交换都需要服务器显式发送此消息。实际上,在大多数情况下,证书消息足以让客户端安全地与服务器通信预主密钥。这些参数的格式完全取决于所选的 CipherSuite,它先前已由服务器通过 ServerHello 消息设置。
| | | Handshake Layer | | - ---+----+----+----+----+----------------+ | 12 | | | | algorithm | |0x0c| | | | parameters | - ---+----+----+----+----+----------------+ / | \ \---------\ / \\ record \ length length\ type: 12
-
CertificateRequest:当服务器需要客户端身份认证时使用。在 Web 服务器中不常用,但在某些情况下非常重要。该消息不仅要求客户端提供证书,它还告诉哪些证书类型是可接受的。此外,它还指示哪些证书颁发机构被认为是值得信赖的。
| | | | Handshake Layer | | - ---+----+----+----+----+----+----+---- - - --+----+----+----+----+-----------+-- - | 13 | | | | | | | | | | | C.A. | |0x0d| | | | | | | | | | |unique name| - ---+----+----+----+----+----+----+---- - - --+----+----+----+----+-----------+-- - / | \ \---------\ \ \ \----\ \-----\ / \ \ \ Certificate \\ record \ length \ Type 1 Id Certificate\ length \ Certificate Authorities length\ type: 13 Types length Certificate Authority length
-
ServerHelloDone:此消息完成握手协商的服务器部分。它不携带任何附加信息。
| | | | Handshake Layer | | - ---+----+----+----+----+ | 14 | | | | 4 |0x0e| 0 | 0 | 0 | - ---+----+----+----+----+ / | \ \---------\ / \\ record \ length: 0 length\ type: 14
-
ClientKeyExchange:它为服务器提供必要的数据来生成对称加密的密钥。消息格式与 ServerKeyExchange 非常相似,因为它主要取决于服务器选择的密钥交换算法。
| | | | Handshake Layer | | - ---+----+----+----+----+----------------+ | 16 | | | | algorithm | |0x10| | | | parameters | - ---+----+----+----+----+----------------+ / | \ \---------\ / \\ record \ length length\ type: 16
验证服务器的证书后,客户端使用服务器的公钥加密pre_master_secret,一旦计算了主密钥,就应该从内存中删除pre_master_secret
此图假定我们使用AES_256_CBC_SHA,因此每个密钥都是32字节长。
主密钥的长度取决于密钥交换算法。
通信是双向的,因此两个方向都使用单独的键:
client_write密钥用于保护从客户端到服务器的数据;server_write密钥用于保护从服务器到客户端的数据
-
CertificateVerify:客户端使用此消息来证明服务器拥有与其公钥证书对应的私钥。该消息包含由客户端数字签名的散列信息。如果服务器向客户端发出 CertificateRequest,则它是必需的,因此它必须发送需要验证的证书。再一次,信息的确切大小和结构取决于商定的算法。在所有情况下,作为散列函数输入的信息都是相同的。
| | | | Handshake Layer | | - ---+----+----+----+----+----------+ | 15 | | | | signed | |0x0f| | | | hash | - ---+----+----+----+----+----------+ / | \ \---------\ / \\ record \ length length\ type: 15
-
Finished:此消息表明 TLS 协商已完成并且 CipherSuite 已激活。它应该已经加密发送,因为协商成功完成,所以必须在此之前发送 ChangeCipherSpec 协议消息以激活加密。Finished 消息包含所有先前握手消息组合的哈希,后跟一个特殊数字标识服务器/客户端角色、主密钥和填充。生成的散列与 CertificateVerify 散列不同,因为有更多的握手消息。
| | | | Handshake Layer | | - ---+----+----+----+----+----------+ | 20 | | | | signed | |0x14| | | | hash | - ---+----+----+----+----+----------+ / | \ \---------\ / \\ record \ length length\ type: 20
TLS 数据传输
握手和数据包都在TLS记录中。
区别是什么?
- 数据包没有握手头,直接所有数据。
- 整个有效载荷也被加密。•ChangeCipherSpec之后的所有数据包都将被加密(仅记录头为纯文本)
用TLS记录协议发送数据流程:
-
碎片化处理
纯文本到TLS纯文本:内容类型、协议版本、长度和片段。
内容类型:change_cipher_spec、alert、handshake、application_data。 -
压缩(可选)
TLSPlaintext到TLSCompressized:内容类型(与以前相同)、协议版本(与以前一样)、长度(不同的值)和片段(压缩形式)。
-
MAC+加密:(ChangeCipherSpec之后)
TLS压缩为TLSCiphertext:内容类型、协议版本、长度(不同)、片段+MAC+填充+填充长度(加密)
-
生成的MAC(例如,由客户端生成):
HMAC_hash(client_write_MAC_key, client_write_seq_num + TLSCompressed.type + TLSCompressed.version
+ TLSCompressed.length + TLSCompressed.fragment)
-
MAC包括一个序列号,以便可以检测到丢失的、额外的或重复的消息。
-
TLSCiphertext是对整个TLSCompressified进行加密的结果和MAC:
- 使用client_write_key和client_write_IV进行块密码加密
警告协议
如果连接或安全变得不稳定、受损或发生严重错误,警报协议允许发送方通知对方。这些消息有两种类型,警告或致命。警告消息表明会话不稳定,并允许接收者确定是否应继续会话。
一条致命消息告诉收件人连接已被破坏或发生了严重错误。发送者在发送消息后应关闭连接。警报协议还包含有关导致特定连接问题的原因的信息。这可能包括解密失败、未知的证书颁发机构、非法参数等等
警报协议也相当简单。它定义了两个字段:严重性级别和警报描述。第一个字段指示警报的严重性(1 表示警告,2 表示致命),而第二个字段编码确切的条件。支持的警报描述取决于 SSL/TLS 版本。
|
|
|
Record Layer | Alert Layer
|
|
+----+----+----+----+----+----+----+
| 21 | | | | | | |
|0x15| | | 0 | 2 | | |
+----+----+----+----+----+----+----+
/ / |
/ / |
type: 21 / |
/
/
length: 2
Alert severity dec hex
----------------------------------------
WARNING 1 0x01
FATAL 2 0x02
TLS 1.0 Alert descriptions dec hex
----------------------------------------
CLOSE_NOTIFY 0 0x00
UNEXPECTED_MESSAGE 10 0x0A
BAD_RECORD_MAC 20 0x14
DECRYPTION_FAILED 21 0x15
RECORD_OVERFLOW 22 0x16
DECOMPRESSION_FAILURE 30 0x1E
HANDSHAKE_FAILURE 40 0x28
NO_CERTIFICATE 41 0x29
BAD_CERTIFICATE 42 0x2A
UNSUPPORTED_CERTIFICATE 43 0x2B
CERTIFICATE_REVOKED 44 0x2C
CERTIFICATE_EXPIRED 45 0x2D
CERTIFICATE_UNKNOWN 46 0x2E
ILLEGAL_PARAMETER 47 0x2F
UNKNOWN_CA 48 0x30
ACCESS_DENIED 49 0x31
DECODE_ERROR 50 0x32
DECRYPT_ERROR 51 0x33
EXPORT_RESTRICTION 60 0x3C
PROTOCOL_VERSION 70 0x46
INSUFFICIENT_SECURITY 71 0x47
INTERNAL_ERROR 80 0x50
USER_CANCELLED 90 0x5A
NO_RENEGOTIATION 100 0x64
记录格式协议
TLS 记录标头包含三个字段,这些字段是允许在其上构建更高层所必需的:
- 字节 0:TLS 记录类型
- 字节 1-2:TLS 版本(主要/次要)
- 字节 3-4:记录中的数据长度(不包括标头本身)。支持的最大值为 16384 (16K)。
record type (1 byte)
/
/ version (1 byte major, 1 byte minor)
/ /
/ / length (2 bytes)
/ / /
+----+----+----+----+----+
| | | | | |
| | | | | | TLS Record header
+----+----+----+----+----+
Record Type Values dec hex
-------------------------------------
CHANGE_CIPHER_SPEC 20 0x14
ALERT 21 0x15
HANDSHAKE 22 0x16
APPLICATION_DATA 23 0x17
Version Values dec hex
-------------------------------------
SSL 3.0 3,0 0x0300
TLS 1.0 3,1 0x0301
TLS 1.1 3,2 0x0302
TLS 1.2 3,3 0x0303
TLS会话和连接
TLS协议是一种非对称协议,用于区分客户端和服务器。
- TLS会话是有状态的。
- 它是TLS握手协议,用于创建和协调客户端和服务器的状态
区分两个对等体之间的会话和连接:
最初,两个对等方在它们之间建立TLS会话(六个状态,主要是CipherSpec和主密钥),然后在它们之间创建TLS连接(另外十个状态,大部分是密钥和IV)。
稍后,两个对等方可以从同一会话建立另一个连接,即会话重用(另一组密钥和IV)
TLS六个会话状态:
- 会话标识符:服务器选择用于标识活动会话状态的任意字节序列。
- 对等认证(可选):对等方的X509.v3证书
- 压缩方法:用于在加密之前压缩数据的算法
- CipherSpec:指定批量数据加密算法和MAC算法。还定义加密属性,例如哈希大小
- 主密钥:客户端和服务器之间共享的48字节密钥
- 是否可恢复:一个标志,指示会话是否可用于启动新连接(允许会话重用?)
TLS五个连接状态
服务器和客户端随机:服务器和客户端为每个连接选择的字节序列
服务器(客户端)写入MAC机密:在对服务器(客户机)写入的数据进行MAC操作时使用的机密
服务器(客户机)写入密钥:由服务器(客户)加密并由客户机(服务器)解密的数据的
批量密码密钥
。服务器(客户端)写入IV:用于密码块链接(CBC)
服务器(客户端)写入序列号:各方为每个连接的传输/接收消息维护单独的序列号。
本文来自博客园,作者:ivanlee717,转载请注明原文链接:https://www.cnblogs.com/ivanlee717/p/16807760.html