大家好,今天来介绍tls1.2握手过程的问题,以下是渲大师小编对此问题的归纳和整理,感兴趣的来一起看看吧!
SSL/TLS中的握手协议
本文是对 HTTP—TCP/IP—SOCKET理解及浅析 的补充,如有需要,请查看上篇文章。
SSL协议由Netscape公司开发,历史可以追溯到Netscape Navigator浏览器统治互联网的时代。
1996年5月, TLS工作组成立,开始将SSL从Netscape迁移至IETF。由于Microsoft和Netscape当时正在为Web的统治权争得不可开交,整个迁移过程进行得非常缓慢、艰难。最终, TLS 1.0于1999年1月问世,见RFC 2246。
尽管与SSL 3相比,版本修改并不大,但是为了取悦Microsoft,协议还是进行了更名😂 。
2006年4月,下一个版本TLS 1.1才问世,仅仅修复了一些关键的安全问题。然而,协议的重要更改是作模悔为TLS扩展于2003年6月发布的,并被集成到了协议中,这比大家的预期早了好几年。
2008年8月, TLS 1.2发布。该版本添加了对已验证加密的支持,并且基本上删除了协议说明中所有硬编码的安全基元,使协议完全弹性化。
SSL和TLS都是加密协议,旨在基于不安全的基础设施提供安全通信。
这意味着,如果正确部署这些协议,你就可以对互联网上的任意一个服务打开通信信道,并且可以确信你会与正确的旦隐正服务器通信,安全地交换信息(你的数据不会被他人截取,而且在接收时会保持原样)。这些协议保护着通信链路即传输层,这也是TLS名称的由来。
安全不是TLS的唯一目标。 TLS实际上有以下四个主要目标(按优先顺序排列)。
互联网的核心是建立在IP( internet protocol)和TCP( transmission control protocol)协议之上的,这些协议用于将数据分割成小数据包进行传输。IP和TCP不是唯一易受攻击的协议,还有一系列其他路由协议用于协助发现网络上的其他计算机。
如果部署了加密,攻击者也许有能力得到加密数据的访问权限,但是不能解密数据携掘或者篡改数据。为了避免伪装攻击, SSL和TLS依赖另外一项被称为公钥基础设施( public key infrastructure,PKI)的重要技术,确保将流量发送到正确的接收端。
为了理解SSL和TLS的运作,我们需要从描述网络通信的理论模型入手,即开放系统互联( open systems interconnection, OSI)模型,参见表1-1。简单来说,所有功能都被映射到七个层上。最底层是最接近物理通信链路的层,后面的层依次建立在其他层之上,提供更高级别的抽象。最顶层就是应用层,携带着应用数据。
以这种方式安排通信可以清晰地划分概念:高层的协议不必担心在底层实现的功能。进一步说,不同层次的协议可以加入通信或者从通信中删除,一种底层协议可以服务于多种上层协议SSL和TLS是这一原则如何在实践中运用的一个重要示例。它用于TCP协议之上,上层协议(如HTTP)之下。当不需要加密时,可以将TLS从模型中去掉,这并不会对上层协议产生影响(它们将直接与TCP协同工作)。当需要加密时,就可以利用TLS加密HTTP,以及其他TCP协议(比如SMTP、 IMAP等)。
握手是TLS协议中最精密复杂的部分。在这个过程中,通信双方协商连接参数,并且完成身份验证。根据使用的功能的不同,整个过程通常需要交换6~10条消息。根据配置和支持的协议扩展的不同,交换过程可能有许多变种。
在使用中经常可以观察到以下三种流程:
2.2.1 完整的握手
每一个TLS连接都会以握手开始。如果客户端此前并未与服务器建立会话,那么双方会执行一次完整的握手流程来协商TLS会话。握手过程中,客户端和服务器将进行以下四个主要步骤。
本节会讨论最常见的TLS握手流程,就是一种在不需要身份验证的客户端与需要身份验证的服务器之间的握手,如图2-2所示。
可以看到,绝大多数消息字段光看名称就很容易理解,而且消息的结构也很容易理解。
服务器无需支持客户端支持的最佳版本。如果服务器不支持与客户端相同的版本,可以提供某个其他版本以期待客户端能够接受。
比方说,公钥算法与套件中使用的必须匹配。除此以外,一些密钥交换算法依赖嵌入证书的特定数据,而且要求证书必须以客户端支持的算法签名。所有这些都表明服务器需要配置多个证书(每个证书可能会配备不同的证书链,Certificate消息是可选的,因为并非所有套件都使用身份验证,也并非所有身份验证方法都需要证书。
更进一步说,虽然消息默认使用X.509证书,但是也可以携带其他形式的标志;一些套件就依赖PGP密钥。
注意ChangeCipherSpec不属于握手消息,它是另一种协议,只有一条消息,作为它的子协议进行实现。这个设计的结果是这条消息不是握手完整性验证算法的一部分,这使得正确实现TLS更为困难。
在2014年6月,人们发现OpenSSL对于ChangeCipherSpec消息的处理不正确,使得OpenSSL为主动网络攻击敞开了大门。同样的问题也出现在其他所有子协议中。主动网络攻击者利用缓冲机制在首次握手时发送未经验证的警报消息,更可以在开始加密以后破环真正的警报消息。为了避免更严重的问题,应用数据协议消息必须等到首次握手完成以后才能开始发送。
这些消息在连接两端都按照各自所见的顺序排列,并以协商新得到的主密钥计算散列。这个过程是通过一个伪随机函数( pseudorandom function, PRF)来完成的,这个函数可以生成任意数量的伪随机数据。我将在本章的后续部分中对其进行介绍。散列函数与PRF一致,除非协商的套件指定使用其他算法。
两端的计算方法一致,但会使用不同的标签:客户端使用client finished,而服务器则使用serverfinished。verify_data = PRF(master_secret, finished_label, Hash(handshake_messages))
因为Finished消息是加密的,并且它们的完整性由协商MAC算法保证,所以主动网络攻击者不能改变握手消息并对vertify_data的值造假。
理论上攻击者也可以尝试找到一组伪造的握手消息,得到的值与真正消息计算出的verity_data的值完全一致。这种攻击本身就非常不容易,而且因为散列中混入了主密钥(攻击者不知道主密钥),所以攻击者根本不会尝试。
在TLS 1.2版本中, Finished消息的长度默认是12字节( 96位),并且允许密码套件使用更长的
长度。在此之前的版本,除了SSL 3使用36字节的定长消息,其他版本都使用12字节的定长消息。
尽管可以选择对任意一端进行身份验证,但人们几乎都启用了对服务器的身份验证。
如果服务器选择的套件不是匿名的,那么就需要在Certificate消息中跟上自己的证书。相比之下,服务器通过发送CertificateRequest消息请求对客户端进行身份验证。消息中列出所有可接受的客户端证书。作为响应,客户端发送自己的Certificate消息(使用与服务器发送证书相同的格式),并附上证书。此后,客户端发CertificateVerify消息,证明自己拥有对应的私钥。
完整的握手如图2-3所示。
只有已经过身份验证的服务器才被允许请求客户端身份验证。基于这个原因,这个选项被称
为相互身份验证( mutual authentication)。
完整的握手协议非常复杂,需要很多握手消息和两次网络往返才能开始发送客户端应用数
据。此外,握手执行的密钥学操作通常需要密集的CPU处理。身份验证通常以客户端和服务器证
书验证(以及证书吊销检查)的形式完成,需要更多的工作。这其中的许多消耗都可以通过简短
握手的方式节约下来。
最初的会话恢复机制是,在一次完整协商的连接断开时,客户端和服务器都会将会话的安全参数保存一段时间。
希望使用会话恢复的服务器为会话指定唯一的标识,称为会话ID。服务器在 ServerHello消息中将会话ID发回客户端(请参见2.2.2节中的示例)。
希望恢复早先会话的客户端将适当的会话ID放入ClientHello消息,然后提交。服务器如果 愿意恢复会话,就将相同的会话ID放入ServerHello消息返回,接着使用之前协商的主密钥生成 一套新的密钥,再切换到加密模式,发送Finished消息。客户端收到会话已恢复的消息以后,也 进行相同的操作。这样的结果是握手只需要一次网络往返。简短握手如图2-4所示。图2-4 简短握手,用于恢复已经建立的会话用来替代服务器会话缓存和恢复的方案是使用会话票证( sesession ticket)。它是2006年引入 的(参见RFC 4507),随后在2008年进行了更新(参见RFC 5077)。使用这种方式,除了所有的状态都保持在客户端(与HTTP Cookie的原理类似)之外,其消息流与服务器会话缓存是一样的。
此文为18年读《HTTPS权威指南》记录内容。如有错误,请批评指正。
HTTPS握手过程
我很早之前写过一篇关于 HTTP 和 HTTPS 的文章,但对于 HTTPS 介绍还不够详细,只讲了比较基础的部分,所以这次我们再来深入一下 HTTPS,用 实战抓包 的方式,带大家再来窥探一次 HTTPS。
对于还不知道对称加密和非对称加密的同学,你先复习我以前的这篇文章 「硬核!30 张图解 HTTP 常见的面试题」, 本篇文章默认大家已经具备了这些知识。
HTTP 由于是明文传输,所谓的明文,就是说客户端与服务端通信的信息都是肉眼可见的,随意使用一个抓包工具都可以截获通信的内容山闹。
所以安全上存在以下三个风险:
HTTP S 在 HTTP 与 TCP 层之间加入了 TLS 协议,来解决上述的风险。
[图片上传失败...(image-93bbca-1618813708342)]
TLS 协议是如何解决 HTTP 的风险的呢?
可见,有了 TLS 协议,能保证 HTTP 通信是安全的了,那么在进行 HTTP 通信前,需要先进行 TLS 握手。TLS 的握手过程,如下图:
上图简要概述来 TLS 的握手过程,其中每一个「框」都是一个记录( record ),记录是 TLS 收发数据的基本单位,类似于 TCP 里的 segment。多个记录可以组合成一个 TCP 包发送,所以 通常经过「四个消息」就可以完成 TLS 握手,也就是需要 2个 RTT 的时延 ,然后就可以在安全的通信环境里发送 HTTP 报文,实现 HTTPS 协议。
所以可以发现,HTTPS 是应用层协议,需要先完成 TCP 连接建立,然后走 TLS 握手过程后,才能建立通信安全的连接。
事实上,不同的密钥交换算法,TLS 的握手过程可能会有一些区别。
这里先简单介绍下密钥交换算法,因为考虑到性能的问题,所以双方在加密应用信息时使用的是对称加密密钥,而对衫源称加密密钥是不能被泄漏的,为了保证对称加密密钥的安全性,所以使用非对称加密的方式来保护对称加密密钥的协商,这个工作就是密钥交换算法负责的。
接下来,我们就以最简单的 RSA 密钥交换算法,来看看它的 TLS 握手过程。
传统的 TLS 握手基本都是使用 RSA 算法来实现密钥交换的,在将 TLS 证书部署服务端时,证书文件中包含一对公私钥,其中公钥会在 TLS 握手阶段传递给客户端,私钥则一直留在服务端,一定要确保私钥不能被窃取。
在 RSA 密钥协商算法中,客户端会生成随机密钥,并使用服务端的公钥加密后再传给服务端。根据非对称加密算法,公钥加密的消息仅能通过私或唯态钥解密,这样服务端解密后,双方就得到了相同的密钥,再用它加密应用消息。
我用 Wireshark 工具抓了用 RSA 密钥交换的 TLS 握手过程,你可以从下面看到,一共经历来四次握手:
对应 Wireshark 的抓包,我也画了一幅图,你可以从下图很清晰地看到该过程:
那么,接下来针对每一个 TLS 握手做进一步的介绍。
客户端首先会发一个「 Client Hello 」消息,字面意思我们也能理解到,这是跟服务器「打招呼」。
消息里面有客户端使用的 TLS 版本号、支持的密码套件列表,以及生成的 随机数( Client Random),这个随机数会被服务端保留,它是生成对称加密密钥的材料之一。
当服务端收到客户端的「Client Hello」消息后,会确认 TLS 版本号是否支持,和从密码套件列表中选择一个密码套件,以及生成 随机数( Server Random)。
接着,返回「 Server Hello 」消息,消息里面有服务器确认的 TLS 版本号,也给出了随机数(Server Random),然后从客户端的密码套件列表选择了一个合适的密码套件。
可以看到,服务端选择的密码套件是 “Cipher Suite: TLS_RSA_WITH_AES_128_GCM_SHA256”。
这个密码套件看起来真让人头晕,好一大串,但是其实它是有固定格式和规范的。基本的形式是「 密钥交换算法 + 签名算法 + 对称加密算法 + 摘要算法 」, 一般 WITH 单词前面有两个单词,第一个单词是约定密钥交换的算法,第二个单词是约定证书的验证算法。比如刚才的密码套件的意思就是:
就前面这两个客户端和服务端相互「打招呼」的过程,客户端和服务端就已确认了 TLS 版本和使用的密码套件,而且你可能发现客户端和服务端都会各自生成一个随机数,并且还会把随机数传递给对方。
那这个随机数有啥用呢?其实这两个随机数是后续作为生成「会话密钥」的条件,所谓的会话密钥就是数据传输时,所使用的对称加密密钥。
然后,服务端为了证明自己的身份,会发送「 Server Certificate 」给客户端,这个消息里含有数字证书。
随后,服务端发了「 Server Hello Done 」消息,目的是告诉客户端,我已经把该给你的东西都给你了,本次打招呼完毕。
在这里刹个车,客户端拿到了服务端的数字证书后,要怎么校验该数字证书是真实有效的呢?
在说校验数字证书是否可信的过程前,我们先来看看数字证书是什么,一个数字证书通常包含了:
那数字证书的作用,是用来认证公钥持有者的身份,以防止第三方进行冒充。说简单些,证书就是用来告诉客户端,该服务端是否是合法的,因为只有证书合法,才代表服务端身份是可信的。
我们用证书来认证公钥持有者的身份(服务端的身份),那证书又是怎么来的?又该怎么认证证书呢?
为了让服务端的公钥被大家信任,服务端的证书都是由 CA ( Certificate Authority ,证书认证机构)签名的,CA 就是网络世界里的公安局、公证中心,具有极高的可信度,所以由它来给各个公钥签名,信任的一方签发的证书,那必然证书也是被信任的。
之所以要签名,是因为签名的作用可以避免中间人在获取证书时对证书内容的篡改。
如下图图所示,为数字证书签发和验证流程:
CA 签发证书的过程,如上图左边部分:
客户端校验服务端的数字证书的过程,如上图右边部分:
但事实上,证书的验证过程中还存在一个证书信任链的问题,因为我们向 CA 申请的证书一般不是根证书签发的,而是由中间证书签发的,比如百度的证书,从下图你可以看到,证书的层级有三级:
对于这种三级层级关系的证书的验证过程如下:
在这四个步骤中,最开始客户端只信任根证书 GlobalSign Root CA 证书的,然后 “GlobalSign Root CA” 证书信任 “GlobalSign Organization Validation CA - SHA256 - G2” 证书,而 “GlobalSign Organization Validation CA - SHA256 - G2” 证书又信任 baidu.com 证书,于是客户端也信任 baidu.com 证书。
总括来说,由于用户信任 GlobalSign,所以由 GlobalSign 所担保的 baidu.com 可以被信任,另外由于用户信任操作系统或浏览器的软件商,所以由软件商预载了根证书的 GlobalSign 都可被信任。
操作系统里一般都会内置一些根证书,比如我的 MAC 电脑里内置的根证书有这么多:
这样的一层层地验证就构成了一条信任链路,整个证书信任链验证流程如下图所示:
最后一个问题,为什么需要证书链这么麻烦的流程?Root CA 为什么不直接颁发证书,而是要搞那么多中间层级呢?
这是为了确保根证书的绝对安全性,将根证书隔离地越严格越好,不然根证书如果失守了,那么整个信任链都会有问题。
客户端验证完证书后,认为可信则继续往下走。接着,客户端就会生成一个新的 随机数 ( pre-master) ,用服务器的 RSA 公钥加密该随机数,通过「 Change Cipher Key Exchange」消息传给服务端。
服务端收到后,用 RSA 私钥解密,得到客户端发来的随机数 (pre-master)。
至此, 客户端和服务端双方都共享了三个随机数,分别是 Client Random、Server Random、pre-master 。
于是,双方根据已经得到的三个随机数,生成 会话密钥(Master Secret) ,它是对称密钥,用于对后续的 HTTP 请求/响应的数据加解密。
生成完会话密钥后,然后客户端发一个「 Change Cipher Spec 」,告诉服务端开始使用加密方式发送消息。
然后,客户端再发一个「 Encrypted Handshake Message(Finishd) 」消息,把之前所有发送的数据做个摘要,再用会话密钥(master secret)加密一下,让服务器做个验证,验证加密通信是否可用和之前握手信息是否有被中途篡改过。
可以发现,「Change Cipher Spec」之前传输的 TLS 握手数据都是明文,之后都是对称密钥加密的密文。
服务器也是同样的操作,发「 Change Cipher Spec 」和「 Encrypted Handshake Message 」消息,如果双方都验证加密和解密没问题,那么握手正式完成。
最后,就用「会话密钥」加解密 HTTP 请求和响应了。
使用 RSA 密钥协商算法的最大问题是不支持前向保密 。因为客户端传递随机数(用于生成对称加密密钥的条件之一)给服务端时使用的是公钥加密的,服务端收到到后,会用私钥解密得到随机数。所以一旦服务端的私钥泄漏了,过去被第三方截获的所有 TLS 通讯密文都会被破解。
为了解决这一问题,于是就有了 DH 密钥协商算法,这里简单介绍它的工作流程。
客户端和服务端各自会生成随机数,并以此作为私钥,然后根据公开的 DH 计算公示算出各自的公钥,通过 TLS 握手双方交换各自的公钥,这样双方都有自己的私钥和对方的公钥,然后双方根据各自持有的材料算出一个随机数,这个随机数的值双方都是一样的,这就可以作为后续对称加密时使用的密钥。
DH 密钥交换过程中, 即使第三方截获了 TLS 握手阶段传递的公钥,在不知道的私钥的情况下,也是无法计算出密钥的,而且每一次对称加密密钥都是实时生成的,实现前向保密 。
但因为 DH 算法的计算效率问题,后面出现了 ECDHE 密钥协商算法,我们现在大多数网站使用的正是 ECDHE 密钥协商算法,关于 ECDHE 握手的过程,将在下一篇揭晓,尽情期待哦。
计算机网络Http/Https基础
一、前言
主要包括:1、http基础:TCP/IP,TCP协议,IP协议,DNS协议,URI与URL;
2、http协议:http报文,http方法,http状态码,常见问题
名词解释:
(1)HTTP(HyperText Transfer Protocol)超文本传输协议
(2)URL(Uniform Resource Locator)统一资源定位符
(3)URI(Uniform Resource Identifer)统一资源标识符
(4)TCP(Transmission Control Protocol)传输控制协议
(5)IP(Internet Protocol)网际协议
(6)UDP(User Data Protocol)用户数据报协议
(7)MAC地址(Media Access Control)媒体访问控制地址/物理地址/硬件地址
(8)ARP协议(Address Resolution Protocol)地址解析协议
二、HTTP基础
2.1TCP/IP
TCP/IP是互联网相关的各类协议族的总称,而http是TCP/IP协议族中的一个子集。
TCP/IP协议族可以分为四层:
(1)应用层:决定向用户提供 应用服务时通信的活动 ,TCP/IP协议族内预存了各类通用的应用服务,如:http,ftp,dns等。
(2)传输层:提供处于网络连接中的两台计算机之间的 数据传输 ,包含两个协议:tcp,udp。
(3)网络层:用来处理 网络上流动的数据包 ,在众多的选项中选择一条传输线路,将数据包传送到对方计算机。包含的协议:IP协议。
(4)数据链路层:用来 处理连接网络的硬件 部分。
2.2 IP协议
IP协议属于网络层,负责处理网络上流动的数据包。为了保证传送成功,搜迹需要满足各类条件,其中两个重要的条件时IP地址和MAC地址。
(1)IP地址,指明了节点被分配到的地址;
(2)MAC地址,指网卡所属的固定地址;
(3)IP地址可以和MAC地址进行配对,高辩IP地址可以变换,但是MAC地址基本上不会世念并更改;
(4)使用ARP地址解析协议可以根据通信方的IP地址反查出对应的MAC地址
2.3 TCP协议
TCP协议位于传输层,提供 可靠的字节流服务 (也就是说,将大数据分隔成以报文段为单位的数据包进行管理)。
为了确保数据准确无误的到达目标处,TCP协议通常采用三次握手策略。
如果在握手的过程中某一个阶段莫名的 中断 了, TCP协议会再次以相同的顺序发送相同的数据包 。
2.4DNS协议
DNS协议位于应用层,提供域名到IP地址之间的解析服务。
2.5 URI和URL
URI是某一个协议方案表示的 资源的定位标识符 ,协议方案是指访问资源所使用的协议类型,如:http,ftp,file等。
URL用字符串标识某一个互联网资源 ,而 URL表示资源的地点,URL是URI的子集。
2.6 HTTP协议
HTTP协议用于客户端和服务器端之间的通信。请求必定由客户端发出,而服务器端回复响应。
HTTP协议不保存状态,为 无状态协议 。这是为了更快的处理大量事务,确保协议的可伸缩性而特意设计的。
但是随着Web的不断发展,这一特性也引发了一些问题,如:如何保持登录状态、如何记录用户信息等,为了解决这一问题,引入了Cookie技术。
2.6.1常见状态码
2XX 成功
200 OK,表示从客户端发来的请求在服务器端被正确处理
204 No content,表示请求成功,但响应报文不含实体的主体部分
205 Reset Content,表示请求成功,但响应报文不含实体的主体部分,但是与 204 响应不同在于要求请求方重置内容
206 Partial Content,进行范围请求
3XX 重定向
301 moved permanently,永久性重定向,表示资源已被分配了新的 URL
302 found,临时性重定向,表示资源临时被分配了新的 URL
303 see other,表示资源存在着另一个 URL,应使用 GET 方法获取资源
304 not modified,表示服务器允许访问资源,但因发生请求未满足条件的情况
307 temporary redirect,临时重定向,和302含义类似,但是期望客户端保持请求方法不变向新的地址发出请求
4XX 客户端错误
400 bad request,请求报文存在语法错误
401 unauthorized,表示发送的请求需要有通过 HTTP 认证的认证信息
403 forbidden,表示对请求资源的访问被服务器拒绝
404 not found,表示在服务器上没有找到请求的资源
5XX 服务器错误
500 internal sever error,表示服务器端在执行请求时发生了错误
501 Not Implemented,表示服务器不支持当前请求所需要的某个功能
503 service unavailable,表明服务器暂时处于超负载或正在停机维护,无法处理请求
2.6.2HTTP报文头部(HTTP首部)
通用字段 作用
Cache-Control 控制缓存的行为
Connection 浏览器想要优先使用的连接类型,比如:keep-alive
Date 创建报文时间
Pragma 报文指令
Via 代理服务器相关信息
Transfer-Encoding 传输编码方式
Upgrade 要求客户端升级协议
Warning 在内容中可能存在错误
请求字段 作用
Accept 能正确接收的媒体类型
Accept-Charset 能正确接收的字符集
Accept-Encoding 能正确接收的编码格式列表
Accept-Language 能正确接收的语言列表
Expect 期待服务端的指定行为
From 请求方邮箱地址
Host 服务器的域名
If-Match 两端资源标记比较
If-Modified-Since 本地资源未修改返回 304(比较时间)
If-None-Match 本地资源未修改返回 304(比较标记)
User-Agent 客户端信息
Max-Forwards 限制可被代理及网关转发的次数
Proxy-Authorization 向代理服务器发送验证信息
Range 请求某个内容的一部分
Referer 示浏览器所访问的前一个页面
TE 传输编码方式
响应字段 作用
Accept-Ranges 是否支持某些种类的范围
Age 资源在代理缓存中存在的时间
ETag 资源标识
Location 客户端重定向到某个 URL
Proxy-Authenticate 向代理服务器发送验证信息
Server 服务器名字
WWW-Authenticate 获取资源需要的验证信息
实体字段 作用
Allow 资源的正确请求方式
Content-Encoding 内容的编码格式
Content-Language 内容使用的语言
Content-Length request body 长度
Content-Location 返回数据的备用地址
Content-MD5 Base64加密格式的内容 MD5检验值
Content-Range 内容的位置范围
Content-Type 内容的媒体类型
Expires 内容的过期时间
Last_modified 内容的最后修改时间
2.6.3 HTTP方法
三、HTTPS基础
HTTPS 还是通过了 HTTP 来传输信息,但是信息通过 TLS 协议进行了加密。
3.1 TLS
TLS 协议位于传输层之上,应用层之下。首次进行 TLS 协议传输需要两个 RTT ,接下来可以通过 Session Resumption 减少到一个 RTT。(RTT表示发送端发送数据到接收到对端数据所需的往返时间)
在 TLS 中使用了两种加密技术,分别为:对称加密和非对称加密。
对称加密:
对称加密就是两边拥有相同的秘钥,两边都知道如何将密文加密解密。
非对称加密:
有公钥私钥之分,公钥所有人都可以知道,可以将数据用公钥加密,但是将数据解密必须使用私钥解密,私钥只有分发公钥的一方才知道。
3.2 TLS 握手过程如下图:
(1)客户端发送一个随机值,需要的协议和加密方式
(2)服务端收到客户端的随机值,自己也产生一个随机值,并根据客户端需求的协议和加密方式来使用对应的方式,发送自己的证书(如果需要验证客户端证书需要说明)
(3)客户端收到服务端的证书并验证是否有效,验证通过会再生成一个随机值,通过服务端证书的公钥去加密这个随机值并发送给服务端,如果服务端需要验证客户端证书的话会附带证书
(4)服务端收到加密过的随机值并使用私钥解密获得第三个随机值,这时候两端都拥有了三个随机值,可以通过这三个随机值按照之前约定的加密方式生成密钥,接下来的通信就可以通过该密钥来加密解密
通过以上步骤可知,在 TLS 握手阶段,两端使用非对称加密的方式来通信,但是因为非对称加密损耗的性能比对称加密大,所以在 正式传输数据 时,两端使用 对称加密 的方式通信。
PS:以上说明的都是 TLS 1.2 协议的握手情况 ,在 1.3 协议中,首次建立连接只需要一个 RTT,后面恢复连接不需要 RTT 了。
四、GET和POST的区别
从技术上说:
1、get请求能缓存,post不能;
2、post相对于get来说,安全一点点,因为get请求都会包含在URL里,会被浏览器保存历史记录,post不会,但是在抓包的情况是一样的。
3、post可以request body来传递比get更多的数据,get米有这个技术。
4、url长度有限制,会影响get请求,长度限制是浏览器限制规定的,不是rfc(互联网通信协议)规定的。
5、post支持更多的 编码类型 且不对 数据类型 限制
TLS 详解
SSL (Secure Sockets Layer) 安全套接层,是一种安全协议,经历了 SSL 1.0、2.0、3.0 版本后发展成了标准安全协议 - TLS (Transport Layer Security) 传输层安全性协议。TLS 有 1.0 (RFC 2246)、1.1(RFC 4346)、1.2(RFC 5246)、1.3(RFC 8446) 版本。
TLS 在实现上分为 记录层 和 握手层 两层,其中握答洞喊手层又含四个子协议: 握手协议 (handshake protocol)、更改加密规范协议 (change cipher spec protocol)、应用数据协议 (application data protocol) 和清野警告协议 (alert protocol)
只需配置浏览器和服务器相关设置开启 TLS,即可实现 HTTPS,TLS 高度解耦,可装可卸,与上层高级应用层协议相互协作又相互独立。
TLS/SSL 的功能实现主要依赖于三类基本算法:散列函数 Hash、对称加密和非对称加密,其利用非对称加密实现身份认证和密钥协商,对称加密算法采用协商的密钥对数据加密,基于散列函数验证信息的完整性。
TLS 的基本工作方式是,客户端使用非对称加密与服务器进行通信,实现身份验证并协商对称加密使用的密钥,然后对称加密算法采用协商密钥对信息以及信息摘要进行加密通信,不同的节点之间采用的对称密钥不同,从而可以保证信息只能通信双方获取。
例如,在 HTTPS 协议中,客户端发出请求,服务端会将公钥发给客户端,客户端验证过后生成一个密钥再用公钥加密后发送给服务端(非对称加密),双方会在颤谨 TLS 握手过程中生成一个协商密钥(对称密钥),成功后建立加密连接。通信过程中客户端将请求数据用协商密钥加密后发送,服务端也用协商密钥解密,响应也用相同的协商密钥。后续的通信使用对称加密是因为对称加解密快,而握手过程中非对称加密可以保证加密的有效性,但是过程复杂,计算量相对来说也大。
记录协议负责在传输连接上交换的所有底层消息,并且可以配置加密。每一条 TLS 记录以一个短标头开始。标头包含记录内容的类型 (或子协议)、协议版本和长度。原始消息经过分段 (或者合并)、压缩、添加认证码、加密转为 TLS 记录的数据部分。
记录层将信息块分割成携带 2^14 字节 (16KB) 或更小块的数据的 TLSPlaintext 记录。
记录协议传输由其他协议层提交给它的不透明数据缓冲区。如果缓冲区超过记录的长度限制(2^14),记录协议会将其切分成更小的片段。反过来也是可能的,属于同一个子协议的小缓冲区也可以组合成一个单独的记录。
压缩算法将 TLSPlaintext 结构转换为 TLSCompressed 结构。如果定义 CompressionMethod 为 null 表示不压缩
流加密(BulkCipherAlgorithm)将 TLSCompressed.fragment 结构转换为流 TLSCiphertext.fragment 结构
MAC 产生方法如下:
seq_num(记录的序列号)、hash(SecurityParameters.mac_algorithm 指定的哈希算法)
块加密(如 RC2 或 DES),将 TLSCompressed.fragment 结构转换为块 TLSCiphertext.fragment 结构
padding: 添加的填充将明文长度强制为块密码块长度的整数倍。填充可以是长达 255 字节的任何长度,只要满足 TLSCiphertext.length 是块长度的整数倍。长度大于需要的值可以阻止基于分析交换信息长度的协议攻击。填充数据向量中的每个 uint8 必须填入填充长度值 (即 padding_length)。
padding_length: 填充长度应该使得 GenericBlockCipher 结构的总大小是加密块长度的倍数。合法值范围从零到 255(含)。 该长度指定 padding_length 字段本身除外的填充字段的长度
加密块的数据长度(TLSCiphertext.length)是 TLSCompressed.length,CipherSpec.hash_size 和 padding_length 的总和加一
加密和 MAC 功能将 TLSCompressed 结构转换为 TLSCiphertext。记录的 MAC 还包括序列号,以便可以检测到丢失,额外或重复的消息。
记录协议需要一种算法,从握手协议提供的安全性参数生成密钥、 IV 和 MAC secret.
主密钥 (Master secret): 在连接中双方共享的一个 48 字节的密钥
客户随机数 (client random): 由客户端提供的 32 字节值
服务器随机数 (server random): 由服务器提供的 32 字节值
握手是 TLS 协议中最精密复杂的部分。在这个过程中,通信双方协商连接参数,并且完成身 份验证。根据使用的功能的不同,整个过程通常需要交换 6~10 条消息。根据配置和支持的协议扩展的不同,交换过程可能有许多变种。在使用中经常可以观察到以下三种流程:(1) 完整的握手, 对服务器进行身份验证;(2) 恢复之前的会话采用的简短握手;(3) 对客户端和服务器都进行身份验证的握手。
握手协议消息的标头信息包含消息类型(1 字节)和长度(3 字节),余下的信息则取决于消息类型:
每一个 TLS 连接都会以握手开始。如果客户端此前并未与服务器建立会话,那么双方会执行一次完整的握手流程来协商 TLS 会话。握手过程中,客户端和服务器将进行以下四个主要步骤:
下面介绍最常见的握手规则,一种不需要验证客户端身份但需要验证服务器身份的握手:
这条消息将客户端的功能和首选项传送给服务器。
是将服务器选择的连接参数传回客户端。
这个消息的结构与 ClientHello 类似,只是每个字段只包含一个选项,其中包含服务端的 random_S 参数 (用于后续的密钥协商)。服务器无需支持客户端支持的最佳版本。如果服务器不支持与客户端相同的版本,可以提供某个其他版本以期待客户端能够接受
图中的 Cipher Suite 是后续密钥协商和身份验证要用的加密套件,此处选择的密钥交换与签名算法是 ECDHE_RSA,对称加密算法是 AES-GCM,后面会讲到这个
还有一点默认情况下 TLS 压缩都是关闭的,因为 CRIME 攻击会利用 TLS 压缩恢复加密认证 cookie,实现会话劫持,而且一般配置 gzip 等内容压缩后再压缩 TLS 分片效益不大又额外占用资源,所以一般都关闭 TLS 压缩
典型的 Certificate 消息用于携带服务器 X.509 证书链 。
服务器必须保证它发送的证书与选择的算法套件一致。比方说,公钥算法与套件中使用的必须匹配。除此以外,一些密钥交换算法依赖嵌入证书的特定数据,而且要求证书必须以客户端支持的算法签名。所有这些都表明服务器需要配置多个证书(每个证书可能会配备不同的证书链)。
Certificate 消息是可选的,因为并非所有套件都使用身份验证,也并非所有身份验证方法都需要证书。更进一步说,虽然消息默认使用 X.509 证书,但是也可以携带其他形式的标志;一些套件就依赖 PGP 密钥
携带密钥交换需要的额外数据。ServerKeyExchange 是可选的,消息内容对于不同的协商算法套件会存在差异。部分场景下,比如使用 RSA 算法时,服务器不需要发送此消息。
ServerKeyExchange 仅在服务器证书消息(也就是上述 Certificate 消息)不包含足够的数据以允许客户端交换预主密钥(premaster secret)时才由服务器发送。
比如基于 DH 算法的握手过程中,需要单独发送一条 ServerKeyExchange 消息带上 DH 参数:
表明服务器已经将所有预计的握手消息发送完毕。在此之后,服务器会等待客户端发送消息。
客户端验证证书的合法性,如果验证通过才会进行后续通信,否则根据错误情况不同做出提示和操作,合法性验证内容包括如下:
由 PKI 体系 的内容可知,对端发来的证书签名是 CA 私钥加密的,接收到证书后,先读取证书中的相关的明文信息,采用相同的散列函数计算得到信息摘要,然后利用对应 CA 的公钥解密签名数据,对比证书的信息摘要,如果一致,则可以确认证书的合法性;然后去查询证书的吊销情况等
合法性验证通过之后,客户端计算产生随机数字的预主密钥(Pre-master),并用证书公钥加密,发送给服务器并携带客户端为密钥交换提供的所有信息。这个消息受协商的密码套件的影响,内容随着不同的协商密码套件而不同。
此时客户端已经获取全部的计算协商密钥需要的信息: 两个明文随机数 random_C 和 random_S 与自己计算产生的 Pre-master,然后得到协商密钥(用于之后的消息加密)
图中使用的是 ECDHE 算法,ClientKeyExchange 传递的是 DH 算法的客户端参数,如果使用的是 RSA 算法则此处应该传递加密的预主密钥
通知服务器后续的通信都采用协商的通信密钥和加密算法进行加密通信
Finished 消息意味着握手已经完成。消息内容将加密,以便双方可以安全地交换验证整个握手完整性所需的数据。
这个消息包含 verify_data 字段,它的值是握手过程中所有消息的散列值。这些消息在连接两端都按照各自所见的顺序排列,并以协商得到的主密钥 (enc_key) 计算散列。这个过程是通过一个伪随机函数(pseudorandom function,PRF)来完成的,这个函数可以生成任意数量的伪随机数据。
两端的计算方法一致,但会使用不同的标签(finished_label):客户端使用 client finished,而服务器则使用 server finished。
因为 Finished 消息是加密的,并且它们的完整性由协商 MAC 算法保证,所以主动网络攻击者不能改变握手消息并对 vertify_data 的值造假。在 TLS 1.2 版本中,Finished 消息的长度默认是 12 字节(96 位),并且允许密码套件使用更长的长度。在此之前的版本,除了 SSL 3 使用 36 字节的定长消息,其他版本都使用 12 字节的定长消息。
服务器用私钥解密加密的 Pre-master 数据,基于之前交换的两个明文随机数 random_C 和 random_S,同样计算得到协商密钥: enc_key = PRF(Pre_master, "master secret", random_C + random_S) ;
同样计算之前所有收发信息的 hash 值,然后用协商密钥解密客户端发送的 verify_data_C,验证消息正确性;
服务端验证通过之后,服务器同样发送 change_cipher_spec 以告知客户端后续的通信都采用协商的密钥与算法进行加密通信(图中多了一步 New Session Ticket,此为会话票证,会在会话恢复中解释);
服务器也结合所有当前的通信参数信息生成一段数据 (verify_data_S) 并采用协商密钥 session secret (enc_key) 与算法加密并发送到客户端;
客户端计算所有接收信息的 hash 值,并采用协商密钥解密 verify_data_S,验证服务器发送的数据和密钥,验证通过则握手完成;
开始使用协商密钥与算法进行加密通信。
HTTPS 通过 TLS 层和证书机制提供了内容加密、身份认证和数据完整性三大功能。加密过程中,需要用到非对称密钥交换和对称内容加密两大算法。
对称内容加密强度非常高,加解密速度也很快,只是无法安全地生成和保管密钥。在 TLS 协议中,最后的应用数据都是经过对称加密后传输的,传输中所使用的对称协商密钥(上文中的 enc_key),则是在握手阶段通过非对称密钥交换而来。常见的 AES-GCM、ChaCha20-Poly1305,都是对称加密算法。
非对称密钥交换能在不安全的数据通道中,产生只有通信双方才知道的对称加密密钥。目前最常用的密钥交换算法有 RSA 和 ECDHE。
RSA 历史悠久,支持度好,但不支持 完美前向安全 - PFS(Perfect Forward Secrecy) ;而 ECDHE 是使用了 ECC(椭圆曲线)的 DH(Diffie-Hellman)算法,计算速度快,且支持 PFS。
在 PKI 体系 一节中说明了仅有非对称密钥交换还是无法抵御 MITM 攻击的,所以需要引入了 PKI 体系的证书来进行身份验证,其中服务端非对称加密产生的公钥会放在证书中传给客户端。
在 RSA 密钥交换中,浏览器使用证书提供的 RSA 公钥加密相关信息,如果服务端能解密,意味着服务端拥有与公钥对应的私钥,同时也能算出对称加密所需密钥。密钥交换和服务端认证合并在一起。
在 ECDH 密钥交换中,服务端使用私钥 (RSA 或 ECDSA) 对相关信息进行签名,如果浏览器能用证书公钥验证签名,就说明服务端确实拥有对应私钥,从而完成了服务端认证。密钥交换则是各自发送 DH 参数完成的,密钥交换和服务端认证是完全分开的。
可用于 ECDHE 数字签名的算法主要有 RSA 和 ECDSA - 椭圆曲线数字签名算法 ,也就是目前密钥交换 + 签名有三种主流选择:
比如我的网站使用的加密套件是 ECDHE_RSA,可以看到数字签名算法是 sha256 哈希加 RSA 加密,在 PKI 体系 一节中讲了签名是服务器信息摘要的哈希值加密生成的
内置 ECDSA 公钥的证书一般被称之为 ECC 证书,内置 RSA 公钥的证书就是 RSA 证书。因为 256 位 ECC Key 在安全性上等同于 3072 位 RSA Key,所以 ECC 证书体积比 RSA 证书小,而且 ECC 运算速度更快,ECDHE 密钥交换 + ECDSA 数字签名是目前最好的加密套件
以上内容来自本文: 开始使用 ECC 证书
关于 ECC 证书的更多细节可见文档: ECC Cipher Suites for TLS - RFC4492
使用 RSA 进行密钥交换的握手过程与前面说明的基本一致,只是没有 ServerKeyExchange 消息,其中协商密钥涉及到三个参数 (客户端随机数 random_C、服务端随机数 random_S、预主密钥 Premaster secret),
其中前两个随机数和协商使用的算法是明文的很容易获取,最后一个 Premaster secret 会用服务器提供的公钥加密后传输给服务器 (密钥交换),如果这个预主密钥被截取并破解则协商密钥也可以被破解。
RSA 算法的细节见: wiki 和 RSA算法原理(二)- 阮一峰
RSA 的算法核心思想是利用了极大整数 因数分解 的计算复杂性
而使用 DH(Diffie-Hellman) 算法 进行密钥交换,双方只要交换各自的 DH 参数(在 ServerKeyExchange 发送 Server params,在 ClientKeyExchange 发送 Client params),不需要传递 Premaster secret,就可以各自算出这个预主密钥
DH 的握手过程如下,大致过程与 RSA 类似,图中只表达如何生成预主密钥:
服务器通过私钥将客户端随机数 random_C,服务端随机数 random_S,服务端 DH 参数 Server params 签名生成 signature,然后在 ServerKeyExchange 消息中发送服务端 DH 参数和该签名;
客户端收到后用服务器给的公钥解密验证签名,并在 ClientKeyExchange 消息中发送客户端 DH 参数 Client params;
服务端收到后,双方都有这两个参数,再各自使用这两个参数生成预主密钥 Premaster secret,之后的协商密钥等步骤与 RSA 基本一致。
关于 DH 算法如何生成预主密钥,推荐看下 Wiki 和 Ephemeral Diffie-Hellman handshake
其核心思想是利用了 离散对数问题 的计算复杂性
算法过程可以抽象成下图:
双方预先商定好了一对 P g 值 (公开的),而 Alice 有一个私密数 a(非公开,对应一个私钥),Bob 有一个私密数 b(非公开,对应一个私钥)
对于 Alice 和 Bob 来说通过对方发过来的公钥参数和自己手中的私钥可以得到最终相同的密钥
而第三方最多知道 P g A B,想得到私钥和最后的密钥很困难,当然前提是 a b P 足够大 (RFC3526 文档中有几个常用的大素数可供使用),否则暴力破解也有可能试出答案,至于 g 一般取个较小值就可以
如下几张图是实际 DH 握手发送的内容:
可以看到双方发给对方的参数中携带了一个公钥值,对应上述的 A 和 B
而且实际用的加密套件是 椭圆曲线 DH 密钥交换 (ECDH) ,利用由椭圆曲线加密建立公钥与私钥对可以更进一步加强 DH 的安全性,因为目前解决椭圆曲线离散对数问题要比因式分解困难的多,而且 ECC 使用的密钥长度比 RSA 密钥短得多(目前 RSA 密钥需要 2048 位以上才能保证安全,而 ECC 密钥 256 位就足够)
关于 椭圆曲线密码学 - ECC ,推荐看下 A Primer on Elliptic Curve Cryptography - 原文 - 译文
尽管可以选择对任意一端进行身份验证,但人们几乎都启用了对服务器的身份验证。如果服务器选择的套件不是匿名的,那么就需要在 Certificate 消息中跟上自己的证书。
相比之下,服务器通过发送 CertificateRequest 消息请求对客户端进行身份验证。消息中列出所有可接受的客户端证书。作为响应,客户端发送自己的 Certificate 消息(使用与服务器发送证书相同的格式),并附上证书。此后,客户端发送 CertificateVerify 消息,证明自己拥有对应的私钥。
只有已经过身份验证的服务器才被允许请求客户端身份验证。基于这个原因,这个选项也被称为相互身份验证(mutual authentication)。
在 ServerHello 的过程中发出,请求对客户端进行身份验证,并将其接受的证书的公钥和签名算法传送给客户端。
它也可以选择发送一份自己接受的证书颁发机构列表,这些机构都用其可分辨名称来表示:
在 ClientKeyExchange 的过程中发出,证明自己拥有的私钥与之前发送的客户端证书中的公钥匹配。消息中包含一条到这一步为止的所有握手消息的签名:
最初的会话恢复机制是,在一次完整协商的连接断开时,客户端和服务器都会将会话的安全参数保存一段时间。希望使用会话恢复的服务器为会话指定唯一的标识,称为会话 ID(Session ID)。服务器在 ServerHello 消息中将会话 ID 发回客户端。
希望恢复早先会话的客户端将适当的 Session ID 放入 ClientHello 消息,然后提交。服务器如果同意恢复会话,就将相同的 Session ID 放入 ServerHello 消息返回,接着使用之前协商的主密钥生成一套新的密钥,再切换到加密模式,发送 Finished 消息。
客户端收到会话已恢复的消息以后,也进行相同的操作。这样的结果是握手只需要一次网络往返。
Session ID 由服务器端支持,协议中的标准字段,因此基本所有服务器都支持,服务器端保存会话 ID 以及协商的通信信息,占用服务器资源较多。
用来替代服务器会话缓存和恢复的方案是使用会话票证(Session ticket)。使用这种方式,除了所有的状态都保存在客户端(与 HTTP Cookie 的原理类似)之外,其消息流与服务器会话缓存是一样的。
其思想是服务器取出它的所有会话数据(状态)并进行加密 (密钥只有服务器知道),再以票证的方式发回客户端。在接下来的连接中,客户端恢复会话时在 ClientHello 的扩展字段 session_ticket 中携带加密信息将票证提交回服务器,由服务器检查票证的完整性,解密其内容,再使用其中的信息恢复会话。
这种方法有可能使扩展服务器集群更为简单,因为如果不使用这种方式,就需要在服务集群的各个节点之间同步会话。
Session ticket 需要服务器和客户端都支持,属于一个扩展字段,占用服务器资源很少。
三次握手、七次握手、四次挥手
TCP/IP 传输协议的 TCP 协议是面向连接的,也就是传输数据之前,必须建立可靠的连接。建立连接的过程中,需交换信息(如选取哪种协议、协议版本等),这个过程称为 握手 handshaking 。
握手过程中会协商后续通信使用的参数,如传输速率、编码方式、校验,袜氏以及其他协议选取、硬件支持的功能等。握手是两个实体之间的通信,但在 TCP/IP 中握手常指 TCP 的三次握手。
TCP 中的数据传输、连接建立与终止都由特定控制参数管理,控制参数有以下这些:
建立 TCP 连接需要三次握手:
TCP 连接的双方通过三次握手确定 TCP 连接的初始序列号、窗口大小以及最大数据段,这样通信双方就能利用连接中的初始序列号保证双方数据段的不重不漏,通过窗口大小控制流量,并使用最大数据段避免 IP 协议对数据包分片。
换个角度看为什么需要三次握手?客户端和服务端通信前要进行连接,三次握手就是为了确保自己和对方的收发能力是正常的。
三次握手后,客户端、服务端才确认了自己的接收、发送能力均是正常的。
HTTP 协议中的数据是明文传输的,任何中间人(man-in-the-middle)都可以读取传输的数据,因此 HTTP 是一种不安全的协议。
HTTPS 是 HyperText Transfer Protocol Secure 的缩写。但 HTTPS 协议自身不告枝散能加密数据,它需要借助 SSL 或 TLS 协议层进行加密。
HTTP 协议和 TLS 协议都位于 application layer。TCP 三次握手建立连接后,使用 TLS 握手建立安全连接,后续使用协商的加密算法先对数据进行加密,再通过 HTTP 传输。
数据加密后,中间人即使获得了数据,也无法读取数据内容,进而避免了中间人攻击(man-in-the-middle-attack)。
HTTP 协议和 TLS 协议一起使用时,称为 HTTPS 协议。App 想要使用 TLS 加密通信,只需网址使用 https:// 前缀即可。
要了解 TLS 工作原理,需先了解加密的工作原理,以及各种加密算法。加密就是将数据从一种格式编码为另一种格式,编码时使用一些数学算法、秘密参数。使用相同算法、参数,可以解密数据,这个过程中的参数称为密钥(key)。
非对称加密算法有两个 key:
最流行的非对称加密算法是 RSA 加密算法,广泛用于密钥交换和数字签名验证。但现在正逐步迁移至更安全高效的 Diffie-Hellman (缩写为 D-H)算法。
非对称加密算法通常速度慢,更耗费 CPU,且 key、数据越长,加密、解搭哪密耗费时间也越长。因此,数据量大时不要使用非对称加密,而应使用对称加密(symmetric key cryptography),对称加密速度更快、性能更高。非对称加密用于传输对称加密密钥。
对称加密算法也称为共享密钥加密(shared key),它使用相同的 key 加密、解密。
对称加密算法主要用于受信任两者之间建立加密通道。因为第三方无法获取对称密钥,因此只有建立通道的双方才可以解密数据。
最流行的对称加密算法是 AES(Advanced Encryption Standard 的缩写,即高级加密标准),
SSL 协议由 Netscape 团队设计,于1995年发布 SSL 2.0版本,之后发布了 SSL 3.0版本,IETF 已于2015年不推荐使用 SSL 3.0。
目前,TLS 协议已经替代了 SSL 协议,SSL 协议已不再使用。
TLS 是旨在提供安全通信的加密协议,使用 TLS 可以加密与服务器的所有通信。当前使用最广的是 TLS 1.2、TLS 1.3。
TLS 1.3 发布于2018年,是对 TLS 1.2 的全面修订,在性能和安全性方面都有很大提升,并且减少了建立安全连接所需的握手次数。
TLS 1.3 只支持 Diffie-Hellman 非对称加密算法,移除了 RSA 算法。
使用 HTTPS 发送 HTTP 请求时,首先使用三次握手建立可靠的 TCP 连接,之后就通过 TLS 四次握手交换双方的密钥。
下面介绍 TLS 1.2 连接建立过程:
TLS 握手的关键在于利用通信双方生成的随机字符串和服务端的公钥生成一个双方经过协商后的密钥,通信双方后续使用这个对称密钥加密数据,防止中间人监听和攻击,保障通信安全。
在 TLS 1.2 中,需要 2-RTT(Round-Trip Time,往返延迟)才能建立 TLS 连接。在 TLS 1.3 中,客户端不仅发送 ClientHello、支持的协议、加密算法,还尝试猜测服务器将选择哪种密钥协商算法,并为此发送共享密钥。这样服务端选取加密算法后,因为已经有了 client key,可以立即生成 key,进而减少一次 RTT。
建立连接时需要发送三个 packet,但终止连接时需要四个 packet,也称为四次挥手。因为 TCP 连接是全双工的,每个方向都必须独立终止。
终止 TCP 连接的四次挥手:
在第二次挥手时,如果服务端也想终止连接,可以为 FIN 设置不同于客户端 FIN 的序列号。客户端收到 FIN 后,发送 ACK,它的 acknowledgement number 为 FIN sequence number 加一。这一过程结束后,服务端与客户端的连接也终止了,这样的话整个过程进行了三次挥手。
客户端想要通过 HTTP 请求访问服务端时,需要经过三次握手;通过 HTTPS 访问服务端时,需要额外增加四次握手。
总结一下 HTTP 建立连接、终止连接:
需要注意的是,本文所说的三次握手、七次握手、四次挥手都是基于特定版本的协议,不同版本的协议所需握手次数可能不同。HTTP/3 就是一个例子,它使用基于 UDP 的 QUIC 协议进行握手,将 TCP 和 TLS 握手过程结合起来,握手次数从七次减少到了三次。
欢迎更多指正: https://github.com/pro648/tips
本文地址: https://github.com/pro648/tips/blob/master/sources/三次握手、七次握手、四次挥手.md
本文地址:https://gpu.xuandashi.com/73744.html,转载请说明来源于:渲大师
声明:本站部分内容来自网络,如无特殊说明或标注,均为本站原创发布。如若本站内容侵犯了原著者的合法权益,可联系我们进行处理。分享目的仅供大家学习与参考,不代表本站立场!