3. HTTP/HTTPS 协议分析:请求方法、状态码、Cookie、HTTPS 握手与证书解密

HTTP 和 HTTPS 是网络世界里最常用的协议。你想想看,我们每天刷网页、看视频、调 API,底层跑的都是它。但 Wireshark 里抓到的 HTTP 包,你真的看透了吗?

我个人习惯,分析 HTTP 问题从来不看应用日志,直接看原始报文。为什么?因为日志可能被框架“美化”过,而报文不会骗人。这一章,我们就来把 HTTP/HTTPS 的底裤扒干净。

3.1 请求方法:不只是 GET 和 POST

很多人觉得请求方法就 GET 和 POST 两种。其实 HTTP/1.1 定义了 8 种方法,但实际常用的就 5 个。

方法 幂等 安全 常见场景
GET 是 是 获取资源,参数在 URL 里
POST 否 否 提交数据,参数在 Body 里
PUT 是 否 上传/替换资源
DELETE 是 否 删除资源
PATCH 否 否 部分更新资源

避坑指南:我曾经排查过一个诡异问题,客户端反复重试请求,导致数据库插入了大量重复订单。一看报文,用的是 POST 请求。POST 不幂等,重试就会出问题。如果换成 PUT,就不会有这种事了。

在 Wireshark 里怎么看请求方法?很简单。抓包后,找到 HTTP 请求包,看 Request Method 字段。或者直接过滤:http.request.method == "POST"。

3.2 状态码:服务器在说什么悄悄话

状态码是服务器给你的“暗号”。我见过不少开发,看到 500 就慌,看到 404 就骂前端。其实每个状态码背后都有故事。

常见的几类状态码:

  • 1xx:信息提示。比如 101 Switching Protocols,WebSocket 升级时会出现。
  • 2xx:成功。200 OK 最常见,201 Created 表示资源创建成功。
  • 3xx:重定向。301 永久重定向,302 临时重定向。我遇到过 CDN 配置错误,导致 301 循环跳转,浏览器直接报错。
  • 4xx:客户端错误。400 Bad Request 通常是参数格式不对,401 未认证,403 禁止访问,404 找不到资源。
  • 5xx:服务端错误。500 内部错误,502 Bad Gateway,503 服务不可用。

重点:304 Not Modified 是个特殊状态码。它告诉客户端:“你缓存的内容还能用,别重新下载了。” 这在优化页面加载速度时非常有用。我在做性能优化时,经常检查 304 的比例,如果太低,说明缓存策略有问题。

Wireshark 过滤状态码:http.response.code == 404。想快速定位所有错误响应?用 http.response.code >= 400。

3.3 Cookie:无状态协议里的“小纸条”

HTTP 本身是无状态的。服务器怎么记住你是谁?靠 Cookie。说白了,就是服务器在你浏览器里贴了一张“小纸条”,下次你来的时候,浏览器会自动带上它。

Cookie 的结构很简单:name=value,后面跟着一堆属性。

属性 含义 示例
Domain 指定哪些域名可以访问该 Cookie .example.com
Path 指定哪些路径可以访问 /
Expires/Max-Age 过期时间 Session(会话级)或具体时间
Secure 仅通过 HTTPS 传输 有/无
HttpOnly 禁止 JavaScript 访问 有/无
SameSite 防止 CSRF 攻击 Strict/Lax/None

注意:我曾经遇到一个线上故障,用户登录后频繁掉线。抓包一看,服务器返回的 Cookie 没有设置 Domain 属性,浏览器默认把它绑定到了子域名上。用户从主站跳到子站,Cookie 就丢了。嗯,这种坑,不抓包根本发现不了。

Wireshark 里看 Cookie:请求包里的 Cookie 字段,响应包里的 Set-Cookie 字段。过滤:http.cookie 或 http.set_cookie。

3.4 HTTPS 握手:TLS 的“三次握手”升级版

HTTPS 就是在 HTTP 外面套了一层 TLS。握手过程比 TCP 三次握手复杂得多。我把它拆成四个阶段:

  1. Client Hello:客户端告诉服务器,我支持哪些 TLS 版本、加密套件。
  2. Server Hello + 证书:服务器选一个加密套件,把证书发给客户端。
  3. 密钥交换:客户端验证证书,生成预主密钥,用服务器公钥加密后发过去。
  4. 握手完成:双方用预主密钥生成会话密钥,之后所有数据都对称加密。
TLS 1.2 握手流程 客户端 服务器 ① Client Hello TLS 版本、加密套件、随机数 ② Server Hello + 证书 选中的加密套件、服务器证书、随机数 ③ 客户端密钥交换 预主密钥(用服务器公钥加密) ④ 握手完成 Change Cipher Spec + Finished 加密数据传输(对称加密) 握手完成后,所有 HTTP 数据都加密传输

个人经验:我排查过一个 HTTPS 慢的问题。抓包发现,TLS 握手阶段,客户端发完 Client Hello 后,等了 2 秒才收到 Server Hello。一看,服务器证书链太长,中间证书没配好。去掉多余的中间证书后,握手时间降到了 200 毫秒。

3.5 证书解密:让 HTTPS 不再“黑盒”

HTTPS 加密后,Wireshark 只能看到一堆乱码。怎么解密?两种方法:

  • 方法一:使用私钥。如果你有服务器的私钥,可以直接导入 Wireshark。路径:Edit → Preferences → Protocols → TLS → RSA keys list。
  • 方法二:使用 SSLKEYLOGFILE。这是我最推荐的方法。设置环境变量 SSLKEYLOGFILE,指向一个文件。浏览器会把会话密钥写进去。Wireshark 读取这个文件,就能解密。

操作步骤:

  1. 关闭所有浏览器实例。
  2. 设置环境变量:export SSLKEYLOGFILE=/tmp/sslkeys.log(Linux/macOS)或 set SSLKEYLOGFILE=C:\sslkeys.log(Windows)。
  3. 启动浏览器,访问目标网站。
  4. Wireshark 中配置:Edit → Preferences → Protocols → TLS → (Pre)-Master-Secret log filename,选择刚才的文件。
  5. 抓包,现在 HTTPS 内容一目了然。

注意:私钥解密只适用于传统 RSA 密钥交换。现在很多服务器用 ECDHE,私钥解密不管用了。SSLKEYLOGFILE 方法通用,支持所有密钥交换算法。我曾经用私钥解密折腾了半天没成功,换成 SSLKEYLOGFILE 后,一分钟搞定。

解密后,你就能看到 HTTP 请求的完整内容了。包括请求头、响应体、Cookie 等等。这对于调试 API、分析恶意流量、排查性能问题,都非常有用。

嗯,这一章的内容就到这里。HTTP/HTTPS 看似简单,但里面的细节很多。下次你遇到网络问题,别急着看日志,先抓个包看看。报文不会骗你。