HTTP/HTTPS 与 TCP 连接过程
网络协议基础:HTTP/HTTPS 区别、GET/POST、三次握手、四次挥手、HTTPS 加密、浏览器访问流程
一、HTTP 与 HTTPS 区别
1.1 对比概览
| 对比项 | HTTP | HTTPS |
|---|---|---|
| 全称 | HyperText Transfer Protocol | HTTP Secure |
| 默认端口 | 80 | 443 |
| 传输方式 | 明文 | 加密(TLS/SSL) |
| 安全性 | 无加密,易被窃听、篡改 | 加密 + 身份认证 |
| 证书 | 不需要 | 需要 CA 证书 |
| 性能 | 略快(无加解密开销) | 略慢(握手 + 加解密) |
| 协议层 | 应用层 | 应用层 + TLS/SSL(介于应用层与传输层之间) |
1.2 HTTP 的问题
- 明文传输:请求和响应内容可被中间人直接读取
- 无身份验证:无法确认对方是否为真实服务器
- 无完整性校验:数据可被篡改而不易被发现
1.3 HTTPS 的改进
- 加密:使用对称加密保护数据内容
- 身份认证:通过 CA 证书验证服务器身份
- 完整性:通过摘要算法(如 SHA-256)防止篡改
二、TCP 三次握手
2.1 目的
建立可靠的双向连接,双方确认彼此的序列号和接收能力。
2.2 过程示意
客户端 服务端
| |
| ① SYN (seq=x) |
| -------------------------------------->|
| 请求建立连接 |
| |
| ② SYN+ACK (seq=y, ack=x+1) |
| <--------------------------------------|
| 确认收到,并请求建立连接 |
| |
| ③ ACK (ack=y+1) |
| -------------------------------------->|
| 确认收到,连接建立 |
| |
| 【连接已建立,可开始传输数据】 |
2.3 各步骤含义
| 步骤 | 报文 | 说明 |
|---|---|---|
| 第一次 | SYN | 客户端发送 SYN,seq=x,表示「我要建立连接,我的初始序列号是 x」 |
| 第二次 | SYN+ACK | 服务端回复 SYN+ACK,seq=y,ack=x+1,表示「收到你的 x,我同意建立连接,我的初始序列号是 y」 |
| 第三次 | ACK | 客户端回复 ACK,ack=y+1,表示「收到你的 y,连接建立完成」 |
2.4 为什么是三次?
- 两次不够:若只有两次握手,服务端无法确认客户端是否收到了自己的 SYN+ACK,可能导致服务端单方面认为连接已建立,而客户端未准备好。
- 三次足够:第三次 ACK 让服务端确认「客户端已收到我的 SYN+ACK」,双方都确认对方具备收发能力。
- 防止历史连接:若客户端之前发出过过期的 SYN,服务端会回复 SYN+ACK;客户端发现是旧连接会回复 RST 终止,不会误建连接。
三、TCP 四次挥手
3.1 目的
优雅关闭连接,确保双方数据都发送完毕后再断开。
3.2 过程示意
客户端 服务端
| |
| ① FIN (seq=u) |
| -------------------------------------->|
| 客户端请求关闭连接(不再发数据) |
| |
| ② ACK (ack=u+1) |
| <--------------------------------------|
| 服务端确认收到 FIN |
| |
| (服务端可能还有数据要发) |
| |
| ③ FIN (seq=v) |
| <--------------------------------------|
| 服务端请求关闭连接 |
| |
| ④ ACK (ack=v+1) |
| -------------------------------------->|
| 客户端确认收到 FIN |
| |
| 【连接关闭】 |
3.3 各步骤含义
| 步骤 | 报文 | 说明 |
|---|---|---|
| 第一次 | FIN | 客户端发 FIN,表示「我不再发送数据了」 |
| 第二次 | ACK | 服务端回 ACK,表示「收到你的关闭请求」;此时连接处于半关闭,服务端仍可向客户端发数据 |
| 第三次 | FIN | 服务端发 FIN,表示「我也不再发送数据了」 |
| 第四次 | ACK | 客户端回 ACK,表示「收到」;连接正式关闭 |
3.4 为什么是四次?
- TCP 是全双工的,每个方向可独立关闭。
- 客户端发 FIN 只表示「我不再发数据」,但服务端可能还有数据要发,所以需要先回 ACK,等数据发完再发 FIN。
- 若服务端没有待发数据,可将第二次 ACK 与第三次 FIN 合并为一次发送(三次挥手),但标准流程是四次。
3.5 TIME_WAIT 状态
客户端在发送第四次 ACK 后会进入 TIME_WAIT(通常 2MSL,约 1–4 分钟):
- 原因:防止第四次 ACK 丢失,服务端会重发 FIN,客户端需要能再次回复 ACK。
- 副作用:该端口在 TIME_WAIT 期间无法被复用,高并发时可能耗尽端口。
四、HTTPS 密钥与加密过程
4.1 混合加密架构
HTTPS 采用混合加密:
- 非对称加密:用于交换对称密钥(如 AES 密钥)
- 对称加密:用于加密实际传输的业务数据
原因:非对称加密计算量大,不适合加密大量数据;对称加密快,适合数据加密。
4.2 TLS 握手流程(简化)
客户端 服务端
| |
| ① Client Hello |
| (支持的 TLS 版本、加密套件、随机数) |
| -------------------------------------->|
| |
| ② Server Hello + 证书 + 公钥 |
| (选定版本、加密套件、服务器随机数) |
| <--------------------------------------|
| |
| ③ 验证证书,生成预主密钥 |
| 用服务器公钥加密预主密钥并发送 |
| -------------------------------------->|
| |
| ④ 服务器用私钥解密,得到预主密钥 |
| 双方用 预主密钥+随机数 生成会话密钥 |
| |
| 【后续通信使用会话密钥对称加密】 |
4.3 密钥类型
| 密钥类型 | 用途 | 特点 |
|---|---|---|
| 公钥 | 加密、验证签名 | 公开,在证书中 |
| 私钥 | 解密、签名 | 仅服务器持有,绝不泄露 |
| 预主密钥 | 由客户端生成,用于推导会话密钥 | 用公钥加密后传输 |
| 会话密钥 | 加密实际数据 | 由预主密钥 + 双方随机数推导,对称密钥 |
4.4 证书与身份认证
- 服务器将公钥放在 CA 签发的证书中。
- 客户端用系统/浏览器内置的 CA 根证书验证服务器证书:
- 证书是否在有效期内
- 域名是否匹配
- 证书链是否可信(由受信任的 CA 签发)
- 验证通过后,才用证书中的公钥加密预主密钥,建立安全通道。
4.5 加密套件示例
TLS_AES_256_GCM_SHA384
- 密钥交换:ECDHE(椭圆曲线 Diffie-Hellman)
- 对称加密:AES-256-GCM
- 摘要算法:SHA-384
五、GET 与 POST 请求的区别
5.1 核心对比
| 对比项 | GET | POST |
|---|---|---|
| 语义 | 获取资源 | 提交/创建资源 |
| 参数位置 | URL 查询串(?key=value) | 请求体(Request Body) |
| 参数可见性 | 明文出现在 URL、历史、日志中 | 通常在 Body 中,相对隐蔽 |
| 数据大小 | 受 URL 长度限制(约 2KB–8KB) | 一般无硬性限制 |
| 缓存 | 可被浏览器、代理缓存 | 一般不缓存 |
| 书签/分享 | 可保存为书签、分享链接 | 通常不可 |
| 幂等性 | 幂等(多次请求结果相同) | 非幂等(可能产生副作用) |
| 安全性 | 参数暴露,不适合敏感信息 | 参数在 Body,相对更安全 |
5.2 使用场景
- GET:查询、列表、详情、搜索等只读操作
- POST:登录、注册、下单、修改数据等会改变状态的操作
5.3 常见误解
- 「GET 不安全、POST 安全」:都不安全。HTTPS 下两者都可加密;HTTP 下 GET 参数在 URL 中更易被记录和泄露。
- 「POST 不能传参到 URL」:POST 也可以带 URL 查询参数,只是通常把业务数据放在 Body。
- 「GET 只能传字符串」:GET 的查询串和 POST 的 form-urlencoded 都是键值对;POST 还可使用 JSON、二进制等格式。
5.4 RESTful 约定
- GET:查询
- POST:创建
- PUT:全量更新
- PATCH:部分更新
- DELETE:删除
六、浏览器输入 HTTPS 网址的完整流程
6.1 整体流程概览
输入 URL → 解析 URL → DNS 解析 → TCP 三次握手 → TLS 握手 → 发送 HTTP 请求
→ 接收响应 → 解析 HTML → 加载子资源 → 渲染页面
6.2 分步说明
| 步骤 | 说明 |
|---|---|
| 1. 输入与解析 URL | 用户输入 https://www.example.com/path?query=1,浏览器解析出协议、主机、路径、查询参数 |
| 2. DNS 解析 | 根据主机名查询 IP,顺序:浏览器缓存 → 系统缓存 → hosts → 本地 DNS → 递归查询 |
| 3. TCP 三次握手 | 建立可靠连接,确认序列号与收发能力 |
| 4. TLS 握手 | Client Hello → Server Hello + 证书 + 公钥 → 密钥交换 → 生成会话密钥 |
| 5. 发送 HTTP 请求 | 在 TLS 加密通道中发送请求行、请求头、请求体 |
| 6. 服务器处理并返回 | 服务器处理请求,返回 HTTP 响应(状态码、响应头、响应体) |
| 7. 浏览器解析响应 | 根据 Content-Type 判断类型,按 Content-Encoding 解压 |
| 8. 解析 HTML 构建 DOM | 词法分析 → Token → 语法分析 → DOM 树 |
| 9. 加载子资源 | 解析 <link>、<script>、<img> 等,发起新请求(可能复用连接) |
| 10. 渲染与布局 | 构建 CSSOM → 渲染树 → Layout → Paint → Composite |
| 11. 执行 JavaScript | 解析执行 JS,可能修改 DOM、发起请求、注册事件 |
6.3 流程示意
┌─────────────┐
│ 1. 输入 URL │
└──────┬──────┘
▼
┌─────────────┐
│ 2. DNS 解析 │ → 获取服务器 IP
└──────┬──────┘
▼
┌─────────────┐
│ 3. TCP 握手 │ → 建立可靠连接
└──────┬──────┘
▼
┌─────────────┐
│ 4. TLS 握手 │ → 建立加密通道
└──────┬──────┘
▼
┌─────────────┐
│ 5. HTTP 请求 │ → 在加密通道中传输
└──────┬──────┘
▼
┌─────────────┐
│ 6. 解析响应 │
└──────┬──────┘
▼
┌─────────────┐
│ 7. 构建 DOM │
└──────┬──────┘
▼
┌─────────────┐
│ 8. 加载资源 │ → CSS、JS、图片等
└──────┬──────┘
▼
┌─────────────┐
│ 9. 渲染页面 │
└─────────────┘
6.4 常见优化
- DNS 预解析:
<link rel="dns-prefetch" href="//example.com"> - 预连接:
<link rel="preconnect" href="https://example.com"> - HTTP/2:多路复用,减少连接数
- 资源预加载:
<link rel="preload">
七、常见问题
Q1:HTTPS 一定比 HTTP 安全吗?
在证书正确、实现无漏洞的前提下,HTTPS 可防止窃听和篡改。若证书被伪造、私钥泄露或实现有漏洞,仍可能不安全。
Q2:为什么 HTTPS 需要证书?
证书用于证明「此公钥属于此域名」,防止中间人伪造服务器公钥进行攻击。
Q3:对称加密的密钥如何安全传递?
通过非对称加密:客户端用服务器公钥加密「预主密钥」后发送,只有持有私钥的服务器能解密,中间人无法获取预主密钥,也就无法推导出会话密钥。
Q4:HTTP/2、HTTP/3 与 HTTPS 的关系?
- HTTP/2 通常基于 HTTPS(TLS)使用
- HTTP/3 基于 QUIC(UDP),可配合 TLS 1.3 使用,加密机制与 HTTPS 类似
参考:RFC 793 (TCP)、RFC 5246 (TLS 1.2)、RFC 8446 (TLS 1.3)