一、HTTP 协议基础
1. 协议定义
- 超文本传输协议(HyperText Transfer Protocol),用于客户端与服务器之间传输数据。
- 无状态性:服务器不保留客户端的上下文信息。
- 示例 :浏览器通过
GET
请求获取网页内容。
2. 请求方法
- GET :获取资源(如
GET /index.html
)。 - POST:提交数据(如表单提交)。
- PUT:上传或替换资源。
- DELETE:删除资源。
- 示例 :
POST /api/login
发送用户登录信息。
3. 状态码
- 200 OK:请求成功。
- 301 Moved Permanently:永久重定向。
- 404 Not Found:资源不存在。
- 500 Internal Server Error:服务器内部错误。
- 示例 :访问
https://example.com/nonexistent
返回404
。
4. 消息结构
-
请求消息:
plaintext
makefileGET /index.html HTTP/1.1 Host: example.com User-Agent: Mozilla/5.0
-
响应消息:
plaintext
yamlHTTP/1.1 200 OK Content-Type: text/html Content-Length: 1234
5. 连接方式
- 短连接:每个请求 / 响应后关闭连接(HTTP/1.0 默认)。
- 长连接 :多个请求复用同一连接(HTTP/1.1 默认,通过
Connection: keep-alive
)。
二、HTTPS 协议基础
1. 协议定义
- HTTP Secure:在 HTTP 基础上加入 SSL/TLS 加密层。
- 加密通信:防止数据被窃听或篡改。
- 示例:电商网站使用 HTTPS 传输用户支付信息。
2. SSL/TLS 协议
-
握手过程:
- 客户端发送支持的加密算法列表。
- 服务器选择加密算法并发送数字证书。
- 客户端验证证书,生成对称密钥(通过服务器公钥加密)。
- 双方使用对称密钥加密通信。
-
示例:Chrome 浏览器地址栏的绿色锁标志表示 SSL/TLS 连接已建立。
3. 数字证书
-
类型:
- 自签名证书:无 CA 签名(用于测试,浏览器会警告)。
- CA 签名证书:由受信任的证书颁发机构(如 DigiCert)签发。
-
验证步骤:
- 检查证书有效期和域名匹配。
- 验证 CA 签名链(从服务器证书到根 CA)。
-
示例 :访问
https://www.google.com
时,浏览器验证 Google 的证书链。
4. 加密算法
- 非对称加密:用于交换对称密钥(如 RSA、ECC)。
- 对称加密:用于数据传输(如 AES-256)。
- 哈希算法:验证数据完整性(如 SHA-256)。
- 示例:客户端使用服务器公钥加密生成的 AES 密钥。
5. 证书钉扎(Certificate Pinning)
- 机制:客户端预存服务器公钥的哈希值,直接比对而非依赖 CA。
- 场景:高安全性应用(如银行 App)防止中间人攻击。
TCP连接
- Http协议是建立在TCP连接之上的通信协议,所以要用Http协议通信首先就需要建立TCP连接,说到TCP连接可能会觉得很陌生,我们换一个词叫"三次握手"可能就会觉得很亲切了,所谓的三次握手就是在建立TCP连接的时候发生的过程。
三次握手
- 首先,由客户端率先发起请求,请求服务器端,这为第一次握手,然后服务器端收到客户端发送的请求后,服务器端进行回应,这是第二次握手,再然后客户端收到服务器端响应的请求后,客户端再次发送请求,表明自己收到服务器端响应的请求,这是第三次握手,此时,客户端和服务器端就建立了TCP连接,就可以进行通信了;所谓的握手其实就是发送请求的过程,我们可以用一个更加直白的例子来便于理解:当一个男孩子见到一个漂亮女孩子的时候,男孩子首先向女孩子搭讪说到:你好,很高兴见到你,我觉得你很漂亮,我很喜欢,能加你的微信交个朋友吗?然后女孩子说:你好,我觉得你也不错,很高兴认识你;再然后男孩子听到女孩子说的话后:我真是太高兴了,既然如此,那我们明天去约会怎么样?
为什么是三次握手,既不是两次也不是四次或者五次呢?
- 首先两次的话只能让客户端知道服务端可以接受到自己的请求,但是无法保证服务器端知道客户端可以收到自己响应的内容,四次五次的话既然客户端和服务器端都知道了可以收到各自的请求或者响应,就没有必要再去浪费网络资源去做无效的请求了。
原因
- 三次握手是为了防止服务器端收到延迟的客户端请求,导致服务器端浪费资源
http传输过程
- 首先,客户端向服务端发送https请求,连接服务器端,然后服务器端会把自己的公钥发送给客户端,客户端拿到服务器端的公钥进行检查,验证是否合理(这一步其实就是验证服务器端的数字证书是否正确),验证之后,合格,客户端会生成一个随机值,也就是客户端的秘钥,然后客户端会用服务器端发过来的公钥去加密自己的秘钥发送给服务器端;然后服务器端拿到客户端发送过来的密文,用自己的私钥解密就得到了客户端的秘钥,然后用秘钥加密发送给客户端的数据,得到密文,最后发送给客户端,再然后,客户端接收到服务器端发送的密文,用自己的秘钥解密就得到了服务器端发送过来的数据了,至此,https传输完成。
客户端验证服务器端数字证书步骤
1. 服务器传送数字证书
服务器会把自身的数字证书发送给客户端,该证书中包含以下内容:
- 服务器的公钥。
- 证书的有效期。
- 服务器的域名(像
*.example.com
这种)。 - 证书颁发机构(CA)的签名。
- 证书链(从服务器证书到根 CA 证书的整条路径)。
2. 客户端开展证书验证工作
客户端会按如下步骤对证书进行验证:
(1)检查基本信息
- 有效期:要保证证书处于有效期限内。
- 域名匹配:确认证书上的域名和正在访问的服务器域名是一致的,以此防范中间人攻击。
(2)验证证书链的真实性
- 根 CA 信任:客户端预先在系统或浏览器中安装了受信任的根 CA 证书。例如,Windows、macOS、Chrome 等系统或软件都内置了这些根证书。
- 构建证书链:从服务器证书开始,逐步向上验证中间 CA 证书,一直追溯到根 CA 证书。
- 验证签名:利用上级 CA 的公钥来验证当前证书的签名是否正确。签名是通过哈希算法和 CA 的私钥生成的,一旦证书内容被篡改,签名验证就会失败。
(3)验证公钥的完整性
- 证书中的公钥是经过 CA 签名保护的,只要签名验证通过,就能确保公钥没有被篡改。
3. 数字签名的原理
- CA 的私钥签名:CA 运用自己的私钥对证书内容(包含公钥)进行加密,生成数字签名。
- 客户端验证:客户端使用 CA 的公钥对签名进行解密,然后将解密后的哈希值与证书内容的哈希值进行对比。若两者相同,就说明证书是完整且未被篡改的。
4. 应对自签名证书的情况
要是服务器使用的是自签名证书(没有经过 CA 签名),客户端默认是不会信任这种证书的,此时会出现警告提示。若要信任该证书,用户需要手动安装自签名证书的公钥,或者在客户端代码中进行配置(例如在开发测试阶段)。
对称加密和非对称加密
- 对称加密:只有一个秘钥,用这一个秘钥加密,也必须用这一个秘钥解密
- 非对称加密:有一个公钥和一个私钥,用公钥加密的内容只能用私钥进行解密,用私钥进行加密的内容只能用公钥进行解密
四次挥手的过程
- 首先是客户端发送请求告知服务器端,我没有什么要发送的东西了,这是第一次挥手,然后服务器端收到客户端的请求后响应,此为第二次挥手,服务器端发送响应告知客户端我没有什么响应要发送给你了,此为第三次挥手,客户端收到服务器端的响应后回应,此为第四次挥手。
原因
- 当客户端发送没有数据的请求时,只能证明客户端没有数据发送给服务器端,但此时还是可以接收服务器端发送的数据,所以只有服务器端也没有数据发送的时候,此时才能证明双方都没有数据发送,此时就可以断开TCP连接了。
三、HTTP 与 HTTPS 的对比
特性 | HTTP | HTTPS |
---|---|---|
端口 | 80 | 443 |
加密 | 明文传输 | SSL/TLS 加密 |
安全性 | 易被窃听、篡改 | 防止中间人攻击 |
信任基础 | 无 | CA 证书链 |
性能 | 快(无加密开销) | 稍慢(加密和解密耗时) |
SEO | 部分搜索引擎降低优先级 | 搜索引擎优先索引 |
四、其他关键知识点
1. HTTP/2 协议
- 多路复用 :一个连接处理多个请求(如
HTTP/2
优化加载速度)。 - 头部压缩:减少传输数据量。
一、多路复用(Multiplexing)
1. 核心原理
- 二进制分帧层 :
HTTP/2 将数据分割为更小的二进制帧(Frame),通过统一的连接传输。每个帧包含 流 ID(Stream ID),用于标识属于哪个请求 / 响应。 - 交错传输 :
多个流(Stream)的帧可以交错发送,服务器和客户端根据流 ID 重组数据。 - 单连接替代多连接 :
替代 HTTP/1.x 的多个 TCP 连接,减少 TCP 握手和 TLS 协商的开销。
2. 关键机制
- 流(Stream) :
双向通信的逻辑通道,每个流由唯一的整数 ID 标识(客户端奇数,服务器偶数)。 - 帧(Frame) :
最小传输单位,包含类型(如 DATA、HEADERS、PRIORITY)和负载数据。 - 优先级(Priority) :
客户端可通过PRIORITY
帧为流设置优先级,服务器优先处理高优先级的流。 - 流量控制(Flow Control) :
通过WINDOW_UPDATE
帧动态调整接收方的缓冲区大小,防止发送方过载。
3. 示例说明
假设客户端请求两个资源(/index.html
和 /style.css
):
plaintext
客户端 → 服务器:
[HEADERS frame, stream=1] 请求 index.html
[HEADERS frame, stream=3] 请求 style.css
[DATA frame, stream=1] 发送 POST 数据(可选)
服务器 → 客户端:
[HEADERS frame, stream=1] 响应 index.html
[DATA frame, stream=1] 返回 HTML 内容
[HEADERS frame, stream=3] 响应 style.css
[DATA frame, stream=3] 返回 CSS 内容
所有帧通过同一个 TCP 连接传输,交错发送,无需等待前一个请求完成。
二、头部压缩(Header Compression)
1. 核心原理
- HPACK 算法 :
通过 静态字典 、动态字典 和 霍夫曼编码 压缩头部字段,减少冗余。 - 索引化(Indexing) :
将常见头部(如Host
、User-Agent
)映射到静态字典的索引,传输时仅需发送索引值。 - 动态学习 :
通信过程中学习新头部,添加到动态字典中,供后续请求复用。
2. 实现细节
- 静态字典 :
预定义常见头部键值对(如:method: GET
、Content-Type: text/html
)。 - 动态字典 :
客户端和服务器维护独立的动态字典,记录首次出现的头部。 - 霍夫曼编码 :
对未被字典索引的字符串进行二进制编码,进一步压缩数据。
3. 示例说明
原始头部:
plaintext
GET /index.html HTTP/1.1
Host: example.com
User-Agent: Mozilla/5.0
HPACK 压缩后:
GET
→ 静态字典索引2
/index.html
→ 霍夫曼编码后的二进制字符串Host: example.com
→ 静态字典索引5
+ 霍夫曼编码的example.com
User-Agent: Mozilla/5.0
→ 静态字典索引17
+ 霍夫曼编码的Mozilla/5.0
最终传输数据格式 :
0x22 0x06 0x00 0x15 ...
(具体二进制流取决于编码)。
三、多路复用与头部压缩的协同优化
-
减少 RTT(往返时间) :
- 多路复用避免了 HTTP/1.x 的队头阻塞(Head-of-Line Blocking)。
- 头部压缩减少了每个请求的头部大小,降低传输延迟。
-
性能对比
特性 HTTP/1.1 HTTP/2 连接数 多个 TCP 连接 单个 TCP 连接 头部开销 明文传输,冗余高 HPACK 压缩,节省 50-90% 并行能力 受限(浏览器通常限制 6 个) 无限制(理论上) 典型页面加载 约 1.5-2 秒 约 0.5-1 秒
四、实际应用中的挑战
- 多路复用的流量控制 :
需合理设置窗口大小,避免因某个流占用过多带宽导致其他流饥饿。 - HPACK 的安全性 :
动态字典可能被攻击者利用(如发送大量新头部耗尽内存),需限制字典大小。 - 兼容性 :
旧版本浏览器或代理可能不支持 HTTP/2,需通过Upgrade
头协商降级。
五、总结
- 多路复用 通过二进制分帧和流 ID 实现高效并发,解决 HTTP/1.x 的性能瓶颈。
- 头部压缩 利用 HPACK 字典和霍夫曼编码大幅减少头部开销。
- 协同作用:两者共同提升 HTTP/2 的吞吐量和响应速度,尤其适用于高并发场景(如电商网站、视频流媒体)。
2. 代理与中间人攻击
- 正向代理:客户端通过代理访问服务器(如 VPN)。
- 反向代理:服务器通过代理接收请求(如 Nginx)。
- 中间人攻击:攻击者窃听并篡改通信(HTTPS 可抵御)。
3. 缓存机制
- HTTP 缓存 :通过
Cache-Control
头控制资源缓存(如max-age=3600
)。 - HTTPS 缓存:浏览器默认不缓存 HTTPS 响应(除非明确配置)。
4. Cookie 与 Session
- HTTP Cookie :存储用户状态(如
Set-Cookie: sessionid=123
)。 - HTTPS Cookie :通过
Secure
属性确保仅 HTTPS 传输。
五、实际应用示例
-
HTTP 请求:
bashcurl http://example.com -v
-
HTTPS 握手过程:
plaintextClientHello → ServerHello + Certificate → ClientKeyExchange → ChangeCipherSpec → Finished
-
自签名证书警告:
plaintextcurl https://self-signed.example.com # 浏览器提示"不安全"
总结
HTTP 是基础通信协议,HTTPS 通过加密和证书机制增强安全性。掌握两者的核心区别(如加密、证书验证)和实际应用场景(如电商、API 接口),能有效应对网络通信中的安全与性能挑战。