目录
SSL和TLS简介
SSL(Secure Sockets Layer)
TLS(Transport Layer Security):
TLS基本原理
TLS在TCP/IP中的位置
基本原理
TLSv1.3
HelloRetryRequest
流程
SSL/TLS是网络安全的基石,广泛应用于互联网上的安全通信,包括HTTPS、安全电子邮件、VPN等多种服务。
SSL协议是为网络通信提供安全性和隐私保护的标准协议,最初由网景公司开发,后来被大部分浏览器和服务器广泛采用。SSL协议经历了以下版本:
SSL 1.0:
SSL 2.0:
SSL 3.0:
1999年,互联网工程任务组(IETF)标准化了SSL的后续版本,并将其命名为TLS(Transport Layer Security,传输层安全),旨在提供更为安全和标准化的加密通讯方式。TLS 1.0(RFC 2246)被认为是SSL 3.1的升级版,它修复了SSL 3.0中的一些安全问题,并提供了向后兼容性。TLS与SSL的主要区别在于它们的安全特性和标准支持。随着TLS版本的迭代,每一代TLS协议都在强化安全措施、去除已知漏洞,并支持更先进的加密算法和技术。
TLS的各个版本及其特点:
TLS 1.0(RFC 2246):
TLS 1.1(RFC 4346):
TLS 1.2(RFC 5246):
TLS 1.3(RFC 8446):
当前,建议使用的版本是TLS 1.3,因其提供了最先进的安全性和性能优化。然而TLS 1.2仍在许多系统和环境中广泛使用。多数浏览器和服务器都已经支持TLS 1.3,并鼓励用户和网站运营者弃用早期版本,以确保网络通信安全。
在TCP/IP模型中没有正式的“安全层”,TLS位于应用层和传输层之间。它使用传输层提供的服务来建立一个安全的通道,然后应用层协议通过这个安全通道传输数据。TLS协议确保了数据的机密性、完整性和认证。
在实际的数据传输中,TLS协议会加密应用层的数据,并将加密后的数据传递给传输层。传输层将这些数据封装在TCP或UDP数据包中,并将它们发送到网络层。网络层进一步封装这些数据包并在网络中传输它们。当数据到达目的地时,这个过程会反向进行,最终应用层会接收到通过TLS解密后的原始数据。
TLS协议在客户端和服务器之间建立安全通信时使用数字证书来进行身份验证,不同版本的流程稍有差异,但是基本原理都一样,下面先大致看一下基本原理:
客户端发起连接:客户端(例如,Web浏览器)向服务器发起一个安全连接请求,通常这是通过在URL中使用https
而不是http
来完成的。
服务器提供证书:作为响应,服务器将自己的数字证书(通常包含服务器的公钥)发送给客户端。这个证书由一个信任的证书颁发机构(CA)签发。
客户端验证证书:客户端接收到服务器的证书后,进行以下检查:
密钥交换:如果证书验证成功,客户端使用证书中的公钥对一个生成的随机密钥(预主密钥)进行加密,并将其发送给服务器。服务器使用自己的私钥解密这个预主密钥。
建立加密会话:客户端和服务器使用预主密钥生成会话密钥,并使用这个密钥对接下来的通信进行加密。
通信:一旦安全通道建立,客户端和服务器就可以开始加密的通信了。
在TLS 1.3中,key_share
是握手过程中的一个重要扩展,它用于在客户端和服务器之间进行密钥交换。这个字段的引入是为了支持Elliptic Curve Diffie-Hellman (ECDHE) 或 Finite Field Diffie-Hellman (DHE) 密钥交换算法。这允许TLS 1.3在只需一次完整的往返通信(1-RTT)的情况下完成握手,从而减少了握手延迟并提高了性能。
key_share
扩展的格式如下:
struct { KeyShareEntry client_shares<0..2^16-1>; } KeyShareClientHello; struct { KeyShareEntry server_share; } KeyShareServerHello; struct { NamedGroup selected_group; } KeyShareHelloRetryRequest;
KeyShareEntry
是一个结构体,它包含了两个字段:group
和key_exchange
。
group
key_exchange
key_exchange
字段包含密钥交换的具体信息。这部分内容取决于选定的group
以及相应的定义。这个字段的内容是二进制的,并且其格式和解释取决于所使用的命名组的类型。比如,对于椭圆曲线组,key_exchange
将包含ECDHE的公钥。在ClientHello
消息中,key_share
扩展的extension_data
字段包含一个KeyShareClientHello
值。这个结构体包含一个client_shares
向量,它是客户端提供的KeyShareEntry
值的列表,按客户端偏好的降序排列。
client_shares
这是客户端提供的密钥共享条目的列表,按照客户端的偏好顺序排列。
客户端提供的KeyShareEntry:
客户端可以提供多个KeyShareEntry
值,每个值代表一组支持的密钥交换参数。客户端不应该为同一个组提供多个KeyShareEntry
值,也不应该为其supported_groups
扩展中未列出的组提供任何KeyShareEntry
值。服务器可以检查这些规则是否被违反,并且如果违反,可以使用"illegal_parameter"警报中止握手。
如果服务器需要客户端使用特定的密钥交换组重试ClientHello
,则它会发送一个HelloRetryRequest
消息。在这条消息中,key_share
扩展的extension_data
字段包含一个KeyShareHelloRetryRequest
值。
selected_group
服务器选择的支持的组,要求客户端为此组重试ClientHello
和KeyShare
。
客户端对HelloRetryRequest的响应
客户端必须验证收到的HelloRetryRequest
中的selected_group
字段
ClientHello
中提供的supported_groups
扩展中的一个组ClientHello
中的key_share
扩展提供的一个组如果以上两点任何检查失败,客户端必须使用"illegal_parameter"警报中止握手。否则,在发送新的ClientHello
时,客户端必须只包含selected_group
字段中指示的组的一个新的KeyShareEntry
。
在ServerHello
消息中,key_share
扩展的extension_data
字段包含一个KeyShareServerHello
值。
server_share
服务器提供的一个KeyShareEntry
值,它必须和客户端的共享中的一个相同的组。
使用(ECDHE)的服务器提供的KeyShareEntry
如果使用(ECDHE)密钥建立,服务器在ServerHello
中提供一个KeyShareEntry
。这个值必须与客户端提供的服务器选择的KeyShareEntry
值在同一个组中。服务器不得为客户端的supported_groups
扩展中未指示的任何组发送KeyShareEntry
,并且在使用"psk_ke"密钥交换模式时不得发送KeyShareEntry
。
如果客户端收到了包含key_share
扩展的HelloRetryRequest
,并且使用(ECDHE)密钥建立,那么客户端必须验证ServerHello
中选定的NamedGroup
是否与HelloRetryRequest
中的相同。如果这个检查失败,客户端必须使用"illegal_parameter"警报中止握手。
基本流程如下:
key_share
(用于密钥交换的公钥材料)、supported_groups
(支持的密钥交换组)、signature_algorithms
(签名算法)和其他TLS扩展。key_share
扩展和其他选择的参数。流程如下图所示:
抓包如下
ClientHello
ServerHello
Certificate
Finished