传输协议https,TCP
文章目录
- 传输协议https,TCP
-
- [一、HTTPS 到底是什么](#一、HTTPS 到底是什么)
- 二、先搞懂三种加密基础
- [三、三次握手属于 TCP,不属于 HTTP](#三、三次握手属于 TCP,不属于 HTTP)
- [四 、TCP协议](#四 、TCP协议)
一、HTTPS 到底是什么
HTTPS = HTTP + TLS。
- HTTP 本身是明文协议,请求和响应在网络上裸传。
- HTTPS 不是新协议,而是让 HTTP 跑在 TLS 这一层加密通道之上。
- 分层看:应用层是 HTTP,下面套一层 TLS,再下面才是 TCP。数据从 HTTP 出来先经 TLS 加密,再交给 TCP 传输。
- 默认端口:HTTP 是 80,HTTPS 是 443。
所以「HTTPS 慢一点」的说法,多出来的开销主要就是 TLS 握手和加解密。
二、先搞懂三种加密基础
握手过程混用了三种密码学工具,先分清楚,后面才看得懂。
- 对称加密
- 加密和解密用同一把密钥。
- 优点:快。缺点:双方得先有同一把密钥,怎么安全地把密钥给对方是难题。
- 代表:AES。
- HTTPS 里真正传业务数据用的就是它。
- 非对称加密(公钥加密)
- 一对密钥:公钥(可公开)和私钥(自己保管)。公钥加密的只有私钥能解,反之亦然。
- 优点:解决了「密钥怎么安全交换」的问题。缺点:慢,不适合加密大量数据。
- 代表:RSA、ECC。
- HTTPS 里用它来在握手阶段安全地协商出那把对称密钥,以及验证身份。
- 哈希 / 摘要 + 数字签名
- 哈希:把任意数据算成固定长度的指纹,数据变一点指纹就全变。代表:SHA-256。
- 数字签名:用私钥对「数据的哈希」加密,别人用公钥能验证「这确实是私钥持有者发的,且没被改」。
- 用途:保证完整性和身份认证(证书就是靠签名来证明可信的)。
一句话概括三者分工:非对称加密负责安全地交换密钥 + 验身份,对称加密负责高效传数据,哈希/签名负责防篡改。
CA(证书颁发机构) 服务器(example.com) 客户端(浏览器) CA(证书颁发机构) 服务器(example.com) 客户端(浏览器) #mermaid-svg-NPtaHkuS9usrXq8V{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-NPtaHkuS9usrXq8V .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-NPtaHkuS9usrXq8V .error-icon{fill:#552222;}#mermaid-svg-NPtaHkuS9usrXq8V .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-NPtaHkuS9usrXq8V .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-NPtaHkuS9usrXq8V .marker{fill:#333333;stroke:#333333;}#mermaid-svg-NPtaHkuS9usrXq8V .marker.cross{stroke:#333333;}#mermaid-svg-NPtaHkuS9usrXq8V svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-NPtaHkuS9usrXq8V p{margin:0;}#mermaid-svg-NPtaHkuS9usrXq8V .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NPtaHkuS9usrXq8V text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-NPtaHkuS9usrXq8V .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-NPtaHkuS9usrXq8V .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-NPtaHkuS9usrXq8V .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-NPtaHkuS9usrXq8V .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-NPtaHkuS9usrXq8V #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-NPtaHkuS9usrXq8V .sequenceNumber{fill:white;}#mermaid-svg-NPtaHkuS9usrXq8V #sequencenumber{fill:#333;}#mermaid-svg-NPtaHkuS9usrXq8V #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-NPtaHkuS9usrXq8V .messageText{fill:#333;stroke:none;}#mermaid-svg-NPtaHkuS9usrXq8V .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NPtaHkuS9usrXq8V .labelText,#mermaid-svg-NPtaHkuS9usrXq8V .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-NPtaHkuS9usrXq8V .loopText,#mermaid-svg-NPtaHkuS9usrXq8V .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-NPtaHkuS9usrXq8V .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-NPtaHkuS9usrXq8V .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-NPtaHkuS9usrXq8V .noteText,#mermaid-svg-NPtaHkuS9usrXq8V .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-NPtaHkuS9usrXq8V .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NPtaHkuS9usrXq8V .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NPtaHkuS9usrXq8V .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-NPtaHkuS9usrXq8V .actorPopupMenu{position:absolute;}#mermaid-svg-NPtaHkuS9usrXq8V .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-NPtaHkuS9usrXq8V .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-NPtaHkuS9usrXq8V .actor-man circle,#mermaid-svg-NPtaHkuS9usrXq8V line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-NPtaHkuS9usrXq8V :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 阶段0:先建立 TCP 连接(三次握手) 阶段1:TLS 握手开始 阶段2:客户端验证证书 阶段3:协商对称会话密钥 阶段4:握手完成确认(已加密) 阶段5:加密数据传输(对称加密,快) SYN 1 SYN-ACK 2 ACK 3 Client Hello 支持的TLS版本 + 加密套件列表 + Client Random 4 Server Hello 选定版本与加密套件 + Server Random 5 发送数字证书(含服务器公钥,CA签名) 6 密钥交换参数(ECDHE)+ 用私钥签名 7 Server Hello Done 8 校验证书:CA是否可信 / 域名是否匹配 是否过期 / 是否吊销 9 用内置根证书验证证书签名(信任链) 10 验证通过,证书可信 11 生成ECDHE临时密钥参数 12 客户端密钥交换参数 13 用 Client Random + Server Random + 共享密钥 计算出会话对称密钥(Session Key) 14 用相同材料计算出相同的会话对称密钥 15 Finished(用会话密钥加密) 16 Finished(用会话密钥加密) 17 加密的 HTTP 请求(AES) 18 加密的 HTTP 响应(AES) 19 后续请求持续复用会话密钥... 20
图里的关键点对应前面讲的原理:
- 阶段 0:HTTPS 底层还是 TCP,先三次握手连上,TLS 才开始。
- 阶段 1(1--7 步):双方交换随机数、协商加密套件、服务器亮出证书。
- 阶段 2(8--10 步):客户端验证证书,这是防中间人/钓鱼的核心环节。
- 阶段 3(11--14 步):通过 ECDHE 各自算出同一把对称密钥,注意这把密钥从没在网上明文传过。
- 阶段 4:双方用新密钥加密发
Finished,能解开就证明通道建成。 - 阶段 5:之后业务数据全用对称密钥加密传输,快且安全。
个人理解TLS:
1. 用非对称加密方式,协商出对称加密密钥;
2. 用这个对称加密密钥作为钥匙,进行数据加密
3. 收到数据后,用这个对称加密的钥匙解密
三、三次握手属于 TCP,不属于 HTTP
三次握手(SYN → SYN-ACK → ACK)是 TCP 协议在建立连接时做的事,目的是让双方确认「我能发、你能收,你能发、我能收」,把一条可靠的传输通道建起来。
HTTP 和 HTTPS 本身不做三次握手,它们是更上层的协议,直接「借用」TCP 已经建好的通道来传数据。
I. 用分层看就清楚了
网络是分层的,从下到上,每一层干自己的事:
| 层 | 协议 | 干什么 | 谁做握手 |
|---|---|---|---|
| 传输层 | TCP | 建立可靠连接、保证数据不丢不乱 | TCP 三次握手在这层 |
| 安全层 | TLS | 在 TCP 通道上加密 | TLS 握手在这层(另一回事) |
| 应用层 | HTTP / HTTPS | 传业务数据(请求、响应) | 不做握手,直接用下层通道 |
所以完整顺序是从下往上一层层建:
- 先 TCP 三次握手 → 建立可靠的传输通道
- (如果是 HTTPS)再 TLS 握手 → 在通道上加密
- 最后才开始传 HTTP 请求/响应
II. 对照两种情况
访问 HTTP 网站(明文):
TCP 三次握手 → 直接发 HTTP 请求
访问 HTTPS 网站(加密):
TCP 三次握手 → TLS 握手 → 发加密的 HTTP 请求
区别就是 HTTPS 在中间多插了一层 TLS 握手,其余一样。
四 、TCP协议
服务器 客户端 服务器 客户端 #mermaid-svg-VXJTiEcNYuwZjsBh{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-VXJTiEcNYuwZjsBh .error-icon{fill:#552222;}#mermaid-svg-VXJTiEcNYuwZjsBh .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-VXJTiEcNYuwZjsBh .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-VXJTiEcNYuwZjsBh .marker{fill:#333333;stroke:#333333;}#mermaid-svg-VXJTiEcNYuwZjsBh .marker.cross{stroke:#333333;}#mermaid-svg-VXJTiEcNYuwZjsBh svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-VXJTiEcNYuwZjsBh p{margin:0;}#mermaid-svg-VXJTiEcNYuwZjsBh .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VXJTiEcNYuwZjsBh text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-VXJTiEcNYuwZjsBh .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-VXJTiEcNYuwZjsBh .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-VXJTiEcNYuwZjsBh #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-VXJTiEcNYuwZjsBh .sequenceNumber{fill:white;}#mermaid-svg-VXJTiEcNYuwZjsBh #sequencenumber{fill:#333;}#mermaid-svg-VXJTiEcNYuwZjsBh #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-VXJTiEcNYuwZjsBh .messageText{fill:#333;stroke:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VXJTiEcNYuwZjsBh .labelText,#mermaid-svg-VXJTiEcNYuwZjsBh .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .loopText,#mermaid-svg-VXJTiEcNYuwZjsBh .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-VXJTiEcNYuwZjsBh .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-VXJTiEcNYuwZjsBh .noteText,#mermaid-svg-VXJTiEcNYuwZjsBh .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-VXJTiEcNYuwZjsBh .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VXJTiEcNYuwZjsBh .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VXJTiEcNYuwZjsBh .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-VXJTiEcNYuwZjsBh .actorPopupMenu{position:absolute;}#mermaid-svg-VXJTiEcNYuwZjsBh .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-VXJTiEcNYuwZjsBh .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-VXJTiEcNYuwZjsBh .actor-man circle,#mermaid-svg-VXJTiEcNYuwZjsBh line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-VXJTiEcNYuwZjsBh :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 三次握手(建立连接) 连接建立,开始传输数据 数据传输... 四次挥手(断开连接) 等待 TIME_WAIT 后真正关闭 SYN=1, seq=x 1 SYN=1, ACK=1, seq=y, ack=x+1 2 ACK=1, seq=x+1, ack=y+1 3 应用数据(HTTP/TLS 等) 4 应用数据 5 FIN=1(我发完了) 6 ACK=1(先确认,可能还有数据要发) 7 FIN=1(我也发完了) 8 ACK=1(确认关闭) 9
I. 三次握手(建立连接)
假设客户端要连服务器:
第 1 次握手:客户端 → 服务器,发 SYN
- 客户端发
SYN=1, seq=x。 - 含义:「我想建立连接,我的初始序号是 x。」
- 此时客户端确认了:我的发送能力正常。
第 2 次握手:服务器 → 客户端,发 SYN + ACK
- 服务器发
SYN=1, ACK=1, seq=y, ack=x+1。 - 含义:「我收到了你的请求(ack=x+1 确认了你的 x),我也同意建立连接,我的初始序号是 y。」
- 此时服务器确认了:我的接收能力正常(收到了客户端的 SYN),我的发送能力也正常(发出了回应)。
第 3 次握手:客户端 → 服务器,发 ACK
- 客户端发
ACK=1, seq=x+1, ack=y+1。 - 含义:「我收到了你的回应(ack=y+1 确认了你的 y),连接确认建立。」
- 此时双方都确认了:客户端的收发正常、服务器的收发正常。
连接建立完成,可以开始传数据。
为什么必须是三次,不能两次?
这是经典问题。关键在于双向确认:
- 前两次握手,只能确认「客户端能发、服务器能收发」,但服务器还不知道客户端能不能收。
- 第三次握手,客户端回 ACK,服务器才确认「客户端也能正常接收」。
如果只有两次,会有个隐患:客户端一个早已失效的、滞留在网络里的旧 SYN 请求,突然到达服务器,服务器以为是新连接就同意了并一直等着,而客户端根本没打算连------白白占用资源。三次握手能让客户端对这个莫名其妙的确认不予理会,避免建立无效连接。
个人理解:
客户端,我要发消息了;
服务器,收到你消息,我也给你发一个你看看能收到吗;
客户端,我收到你消息了
II. 四次挥手(断开连接)
断开比建立多一次,因为 TCP 是全双工(双向都能独立收发),关闭时要两个方向分别关。假设客户端主动断开:
第 1 次挥手:客户端 → 服务器,发 FIN
- 「我没有数据要发了,请求关闭我这个方向。」
第 2 次挥手:服务器 → 客户端,发 ACK
- 「知道了,我先确认。」
- 注意:此时服务器可能还有数据没发完,所以它只先回 ACK,不马上关。这段时间客户端不再发数据,但还能收服务器的数据(半关闭状态)。
第 3 次挥手:服务器 → 客户端,发 FIN
- 等服务器也把数据发完了,才发 FIN:「我这边也没数据了,可以关了。」
第 4 次挥手:客户端 → 服务器,发 ACK
- 「收到,确认关闭。」
- 客户端发完这个 ACK 后会**等待一段时间(TIME_WAIT)**再真正关闭,确保这个 ACK 服务器能收到(万一丢了,服务器会重发 FIN,客户端还能再回)。
为什么挥手是四次、握手是三次? 握手时服务器的 SYN 和 ACK 可以合并成一条一起发(第 2 次)。而挥手时,服务器收到 FIN 后不能马上关(可能还有数据要发),所以 ACK 和 FIN 得分两次发,就多了一次。
四次挥手我的理解:
客户端,我发完了,请求关闭;
服务器,我收到你请求;
服务器,我也发完了;
客户端,收到,我关闭完毕