HTTP 与 TLS 完全学习指南
从零基础到高手:用最浅显的语言、可视化的图解和可以亲手操作的演示,带你彻底搞懂网页背后那套「请求—响应—加密」的运作机制。无论你是刚入门的前端/后端/运维,还是想系统补全网络知识的工程师,这份材料都能陪你走完整个进阶之路。
1. 什么是 HTTP
HTTP(HyperText Transfer Protocol,超文本传输协议)是万维网(World Wide Web)的基石。当你在浏览器地址栏输入一个网址、点开一条链接、刷一下朋友圈,背后几乎都有 HTTP 在默默工作。它规定了客户端(通常是浏览器)和服务器之间如何对话:客户端发「请求」,服务器回「响应」。
1.1 一个生活化的比喻
把 HTTP 想象成餐厅点餐:你(客户端)拿起菜单写下「来一份牛肉面,不要香菜」(请求),交给服务员(网络),后厨(服务器)做好后连同一张小票(响应)端给你。HTTP 就是那张写满格式规范的「点餐单」——它约定了单子上要写什么字段、怎么写、后厨回单又该是什么样子。
1.2 HTTP 的核心特征
| 特征 | 含义 | 带来的影响 |
|---|---|---|
| 无状态(Stateless) | 每个请求之间服务器默认「不记得」上一个请求 | 需要 Cookie / Session / Token 来维持登录态 |
| 明文(早期) | HTTP 本身不加密,数据可被窃听 | 催生了 HTTPS(HTTP + TLS)来补上安全短板 |
| 客户端驱动 | 总是客户端先说话,服务器不能主动推 | 早期靠轮询;HTTP/2 有了服务端推送 |
| 可扩展 | 头部(Header)可自定义,方法可扩展 | 催生出 WebDAV、各类业务头字段 |
| 媒体无关 | 不仅能传 HTML,还能传图片、视频、JSON | 成为一切 Web API 的通用传输层 |
1.3 你每天在用的 HTTP
- 打开
https://www.baidu.com—— 浏览器向百度服务器发 HTTP 请求,拿回 HTML。 - 刷抖音网页版,下滑加载更多视频 —— 背后是 HTTP 请求一个 JSON 接口。
- 手机 App 登录 —— App 用 HTTP 把账号密码发给服务器校验。
- 微信小程序调用后端 —— 本质也是 HTTP/HTTPS 请求。
可以说,只要设备要和服务器「要数据」或「交数据」,十有八九走的就是 HTTP。
2. HTTP 发展历史
HTTP 不是一蹴而就的,它随 Web 的膨胀不断进化。理解版本差异,能帮你解释很多「为什么现在要这么配」的历史包袱。
| 版本 | 年份 | 里程碑 | 现状 |
|---|---|---|---|
| HTTP/0.9 | 1991 | 只有 GET,只能传纯文本 HTML,没有头部 | 已淘汰 |
| HTTP/1.0 | 1996 | 引入状态码、Header、多种内容类型 | 极少见 |
| HTTP/1.1 | 1997/1999 | 持久连接、管线化、分块传输、Host 头 | 至今主流 |
| HTTP/2 | 2015 | 二进制分帧、多路复用、头部压缩、服务端推送 | 快速普及 |
| HTTP/3 | 2022 | 基于 QUIC(跑在 UDP 上),解决队头阻塞 | 新站点逐步采用 |
2.1 为什么 1.1 统治了二十多年
HTTP/1.1 解决了 1.0 最致命的问题:每个请求都要新建一次 TCP 连接太浪费。它引入持久连接(Keep-Alive),一个 TCP 连接可以连续发多个请求。还加了 Host 头,让一台服务器能用同一个 IP 托管多个网站(虚拟主机)——这在今天云主机时代是天经地义的事,但在当年是革命性的。
2.2 1.1 的痛点催生了 2 和 3
但 1.1 仍有硬伤:队头阻塞(Head-of-Line Blocking)。浏览器对同一域名的并发连接数有限(通常 6 个),第 7 个请求得排队;而且 HTTP 头部是纯文本、重复极多(每次都带一堆相同的 Cookie、User-Agent),白白占带宽。HTTP/2 用「多路复用」把所有请求拆成小帧在同一条连接上交错传输,彻底干掉了排队;HTTP/3 更进一步,把底层从 TCP 换成 UDP 之上的 QUIC,连 TCP 层的队头阻塞都解决了。
一句话总结版本演进:0.9 能看 → 1.0 能传 → 1.1 能连 → 2 能快 → 3 能稳。每一代都在补上一代最痛的短板。
3. URL / URI 详解
当你访问 https://www.example.com:443/path/page?name=tom#section 时,这一长串就是 URL。理解它的每一段,是读懂 HTTP 请求的第一步。
3.1 URI、URL、URN 的区别
- URI(统一资源标识符):统称,用来「标识」一个资源。URL 和 URN 都是 URI 的子集。
- URL(统一资源定位符):不仅标识资源,还告诉你去哪找它(有位置信息),如
https://x.com/a。 - URN(统一资源名称):只给名字不管位置,如
urn:isbn:9787111111111(一本书的 ISBN)。现实中极少用。
日常语境下,大家口中的「URL」和「URI」基本可以混用,都指那个网址。但严谨地说,URL ⊂ URI。
3.2 关键组件拆解
| 组件 | 作用 | 默认值 | 备注 |
|---|---|---|---|
| 协议 scheme | 用哪种协议访问 | — | http 用 80 端口,https 用 443 |
| 主机 host | 服务器域名或 IP | — | 会被 DNS 解析成 IP |
| 端口 port | 服务器上的「窗口号」 | http:80 / https:443 | 省略时使用默认端口 |
| 路径 path | 服务器上的资源位置 | / | 类似文件系统路径 |
| 查询 query | 传给服务器的参数 | 无 | ? 开头,& 分隔,= 赋值 |
| 片段 fragment | 页面内锚点 | 无 | # 开头,不会发给服务器 |
#锚点 是给浏览器自己用的,根本不会随 HTTP 请求发到服务器。很多新手以为后端能拿到 location.hash,其实它只存在于浏览器端。4. HTTP 报文结构
报文(Message)就是 HTTP 对话的「信」。客户端发的是请求报文,服务器回的是响应报文。两者结构相似,都由三部分组成:起始行 + 头部(Headers)+ 空行 + 正文(Body)。
4.1 请求报文
POST /login HTTP/1.1 ← 请求行(方法 路径 版本)
Host: www.example.com ← 以下都是请求头
User-Agent: Mozilla/5.0
Content-Type: application/json
Content-Length: 38
Cookie: sessionid=abc123
← 空行(必须,分隔头与体)
{"user":"tom","pass":"123456"} ← 请求体
4.2 响应报文
HTTP/1.1 200 OK ← 状态行(版本 状态码 原因短语)
Content-Type: text/html ← 响应头
Content-Length: 1256
Set-Cookie: sessionid=abc123
← 空行
<html>...页面内容...</html> ← 响应体
4.3 头部规则速记
- 头部不区分大小写(
Content-Type与content-type等价),但约定用首字母大写驼峰。 - 多个相同字段一般不允许(
Set-Cookie是著名例外,可出现多次)。 - 头部之间用
\r\n(回车换行)分隔,头部与 Body 之间用一个空行。 - Body 是否有、有多长,由
Content-Length或Transfer-Encoding: chunked决定。
5. HTTP 请求方法
方法(Method)告诉服务器「我想对这份资源做什么」。最常见的当然是 GET 和 POST,但 HTTP 远不止这两个。
| 方法 | 含义 | 有 Body? | 幂等? | 典型用途 |
|---|---|---|---|---|
| GET | 获取资源 | 否 | 是 | 打开网页、查数据 |
| POST | 提交/新建资源 | 是 | 否 | 登录、发帖、上传 |
| PUT | 完整替换资源 | 是 | 是 | 更新用户资料(整体) |
| PATCH | 局部修改资源 | 是 | 否 | 改一个字段 |
| DELETE | 删除资源 | 可无 | 是 | 注销账号、删评论 |
| HEAD | 只取头部 | 否 | 是 | 探测资源是否存在/多大 |
| OPTIONS | 查询支持的方法 | 否 | 是 | 跨域预检(CORS 预检) |
5.1 GET 与 POST 的误区
很多人背过「GET 参数在 URL,POST 参数在 Body」「GET 不安全,POST 安全」。这两个说法都不准确:
- GET 参数确实常跟在 URL 后(
?x=1),但这只是约定,GET 也能带 Body(少数场景)。 - POST 参数在 Body 里,但 Body 同样是明文,没加密就一样能被抓包看到。安全性来自 HTTPS,不是来自方法。
- 真正区别:GET 语义是「读」,应幂等、可缓存、不该改服务器状态;POST 语义是「写」,可改状态。
/login?user=tom&pass=123)——密码会留在浏览器历史、服务器日志、代理日志里,极不安全。密码永远走 POST + HTTPS。5.2 幂等(Idempotent)是什么
幂等指「同一个请求发 1 次和发 10 次,服务器最终状态一样」。GET、PUT、DELETE 是幂等的(删一次和删十次,资源都没了);POST 不是(发十次可能创建十个订单)。这个性质对网络重试至关重要:断网重发一个幂等请求是安全的,重发非幂等请求得小心。
6. HTTP 状态码
状态码是服务器用三位数字给请求的「判决书」。记住它的分类规律,你就能一眼猜出大部分错误。
| 码 | 名称 | 含义与处理 |
|---|---|---|
| 200 | OK | 成功,Body 里有你要的数据 |
| 201 | Created | 创建成功(POST 新建资源后常见) |
| 204 | No Content | 成功但无返回体(如 DELETE 成功) |
| 301 | Moved Permanently | 永久重定向,浏览器会缓存并直接跳新地址 |
| 302 | Found | 临时重定向(登录后跳回原页常用) |
| 304 | Not Modified | 缓存命中,直接用本地副本,不传 Body |
| 400 | Bad Request | 请求语法错(参数格式不对) |
| 401 | Unauthorized | 未认证(没登录 / Token 失效) |
| 403 | Forbidden | 登录了但没权限(如普通用户访问管理员页) |
| 404 | Not Found | 资源不存在(网址拼错最常见) |
| 429 | Too Many Requests | 限流:你请求太频繁了 |
| 500 | Internal Server Error | 服务器代码抛异常 |
| 502 | Bad Gateway | 网关/代理从上游拿到无效响应(Nginx 后端的程序挂了常见) |
| 503 | Service Unavailable | 服务器过载或维护中 |
| 504 | Gateway Timeout | 网关等待上游超时 |
7. 常见请求头与响应头
头部是 HTTP 的「元数据层」,承载了缓存、身份、内容协商等大量信息。下面按功能分类列出最常用的。
7.1 通用头(请求响应都可能出现)
| 头字段 | 作用 | 示例 |
|---|---|---|
Cache-Control | 缓存策略总开关 | max-age=3600, public |
Connection | 是否保持连接 | keep-alive / close |
Date | 报文生成时间 | Mon, 24 Aug 2026 14:00:00 GMT |
Transfer-Encoding | 传输编码(分块) | chunked |
7.2 请求头(客户端 → 服务器)
| 头字段 | 作用 | 示例 |
|---|---|---|
Host | 目标主机(虚拟主机必需) | www.example.com |
User-Agent | 客户端身份(浏览器/系统) | Mozilla/5.0 (Windows NT...) |
Accept | 能接收的内容类型 | text/html, application/json |
Authorization | 认证凭据(Token/签名) | Bearer eyJhbGci... |
Cookie | 携带服务器之前发的状态 | sessionid=abc123 |
Referer | 从哪个页面跳来的 | https://www.google.com/ |
Origin | 跨域请求的来源域 | https://a.com |
If-None-Match | 缓存验证(带上次 ETag) | "abc123" |
7.3 响应头(服务器 → 客户端)
| 头字段 | 作用 | 示例 |
|---|---|---|
Content-Type | 响应体类型与编码 | text/html; charset=utf-8 |
Content-Length | 响应体字节数 | 1256 |
Set-Cookie | 让浏览器存 Cookie | sessionid=abc; Path=/; HttpOnly |
Location | 重定向目标(配合 3xx) | https://new.example.com |
ETag | 资源版本标识(缓存用) | "abc123" |
Server | 服务器软件信息 | nginx/1.25.0 |
Strict-Transport-Security | 强制 HTTPS(HSTS) | max-age=31536000 |
Access-Control-Allow-Origin | 跨域允许的来源 | * 或 https://a.com |
Server 头隐藏或伪装(如 Nginx 的 server_tokens off;),少暴露版本号就少给攻击者提供「按版本找漏洞」的线索。8. HTTP 与 TCP/IP:它跑在哪一层
很多初学者搞混:「HTTP 和 TCP 是什么关系?」答案是——HTTP 是「说话的内容」,TCP 是「送信的邮差」。HTTP 报文必须装进 TCP 连接里才能传输。
8.1 网络分层模型
你可以这样理解封装:HTTP 报文 → 被 TCP 切成段并编号 → 被 IP 加上源/目标地址 → 被网卡变成电信号。到对端后层层拆包,服务器最终拿到原始 HTTP 报文。
8.2 TCP 三次握手(建立连接)
在发 HTTP 请求前,客户端和服务器要先通过 TCP 三次握手确认「双方收发都正常」,才能建立可靠连接。这是 HTTPS 慢一点的根源之一(TLS 还要再握一次手)。
为什么不是两次?因为若只有两次,服务器无法确认客户端的接收能力是否正常。三次握手用最小代价验证了双向通道可用,同时同步了双方的初始序列号。
8.3 TCP 四次挥手(断开连接)
数据传输完,双方要断开连接。由于 TCP 是全双工的(两个方向独立),每个方向都要单独关闭,所以需要四次:A 说「我发完了」→ B 回「知道」→ B 说「我也发完了」→ A 回「知道,拜拜」。
9. Cookie 与 Session:如何让无状态的 HTTP 记住你
HTTP 天生「健忘」,每个请求都像第一次见面。但网站要登录、要记住购物车,怎么办?答案是 Cookie + Session 这套经典组合。
9.1 Cookie:服务器让浏览器存的小纸条
流程是这样的:
- 你第一次登录,服务器验证账号密码正确。
- 服务器在响应头里放
Set-Cookie: sessionid=abc123。 - 浏览器把这个键值对存到本地(按域名隔离)。
- 之后你每次访问该网站,浏览器自动在请求头里带上
Cookie: sessionid=abc123。 - 服务器读到这个 id,就知道「哦,是刚刚登录的那个人」。
9.2 Session:服务器那边的「账本」
Cookie 里只存一个随机 id(sessionid),真正的用户数据(用户名、权限、购物车)存在服务器的 Session 存储里(内存、Redis、数据库等)。服务器用这个 id 去账本里查对应的数据。
| 对比 | Cookie | Session |
|---|---|---|
| 存哪 | 客户端浏览器 | 服务器端 |
| 安全性 | 可被篡改/查看(要签名或加密) | 用户拿不到,较安全 |
| 容量 | 单域名约 4KB,数量有限 | 理论上无限制(受服务器资源约束) |
| 生命周期 | 可设过期时间,或关浏览器即清 | 服务器控制,常设超时(如 30 分钟无操作失效) |
9.3 Cookie 的安全属性
| 属性 | 作用 |
|---|---|
HttpOnly | 禁止 JS 读取,防 XSS 偷 Cookie |
Secure | 只在 HTTPS 下传输,防明文泄露 |
SameSite | 限制跨站携带,防 CSRF(推荐 Lax 或 Strict) |
Path / Domain | 限制 Cookie 生效的子路径/子域 |
Max-Age / Expires | 过期时间 |
Set-Cookie: sessionid=abc123; Path=/; HttpOnly; Secure; SameSite=Lax; Max-Age=3600
9.4 现代替代:Token(JWT)
移动互联网和前后端分离流行后,JWT(JSON Web Token)这类「无状态令牌」更受欢迎:服务器不存 Session,把一个签过名的 JSON(含用户 id、过期时间)发给前端,前端每次请求在 Authorization: Bearer xxx 头里带上。服务器用密钥验证签名即可信任,无需查账本——特别适合多台服务器/微服务横向扩展。缺点是令牌发出去在过期前难以主动吊销。
10. 缓存机制:让网页飞起来的关键
缓存是 Web 性能的第一杠杆。据 Google 统计,大量请求其实可以用本地副本满足,根本不必再问服务器。HTTP 缓存就是一套「什么时候可以放心用旧数据」的规则。
10.1 两类缓存
| 类型 | 存哪 | 是否问服务器 | 控制头 |
|---|---|---|---|
| 强缓存 | 本地,有效期内直接用 | 完全不问 | Cache-Control / Expires |
| 协商缓存 | 本地有副本但需确认是否过期 | 问一次,未变则 304 | ETag / Last-Modified |
10.2 强缓存:Cache-Control
Cache-Control 是现代缓存的核心,常用指令:
| 指令 | 含义 |
|---|---|
max-age=3600 | 缓存 3600 秒(1 小时)内直接用 |
public | 任何缓存(浏览器、CDN)都可存 |
private | 仅用户浏览器可存,CDN 不可 |
no-cache | 每次都得先问服务器确认(走协商缓存) |
no-store | 禁止任何缓存(敏感数据用) |
must-revalidate | 过期后必须回源确认,不能用过期副本 |
# 静态资源:长期缓存 + 文件名带哈希(内容变则文件名变)
Cache-Control: public, max-age=31536000, immutable
# HTML 文档:每次都确认,保证拿到最新
Cache-Control: no-cache
10.3 协商缓存:ETag 与 Last-Modified
强缓存过期后,浏览器带着「我之前那份的标签」去问服务器:
Last-Modified:资源最后修改时间。请求时带If-Modified-Since。ETag:资源的唯一指纹(如内容哈希)。请求时带If-None-Match。
服务器比对后发现「没变」,就回 304 Not Modified,不传 Body,浏览器用本地副本——既保证了新鲜度,又省了流量。
no-cache 保证始终最新。这是几乎所有现代前端构建工具(Webpack/Vite)的默认策略。11. 持久连接、管线化与多路复用
「一个 TCP 连接能发几个请求?」这个问题贯穿了 HTTP 的进化史。
11.1 短连接 → 持久连接
- HTTP/1.0 短连接:每个请求新建 TCP,用完即关。三次握手开销被重复支付,极慢。
- HTTP/1.1 持久连接(默认 Keep-Alive):一个 TCP 连接顺序发多个请求。配合
Connection: keep-alive(1.1 默认开启)。
11.2 管线化(Pipelining)与队头阻塞
1.1 的持久连接仍是串行的:请求 1 的响应没回来,请求 2 不能发(因为要按顺序对应)。「管线化」尝试一次性把请求 1、2、3 都发出去,但响应仍须按序返回——只要请求 1 慢,后面全堵死,这叫队头阻塞。浏览器出于兼容性几乎没启用管线化,反而用「开 6 个连接」来并行。
12. 内容协商(Content Negotiation)
同一个 URL,服务器可能提供多种格式/语言/编码的版本。内容协商让客户端「声明偏好」,服务器「挑最合适的」回。
| 维度 | 请求头 | 示例 |
|---|---|---|
| 媒体类型 | Accept | application/json vs text/html |
| 语言 | Accept-Language | zh-CN,en;q=0.8 |
| 编码 | Accept-Encoding | gzip, br, deflate |
| 字符集 | Accept-Charset | utf-8 |
q 是质量因子(0~1),表示偏好程度。例如 Accept-Language: zh-CN,en;q=0.8 意为「首选简体中文,其次英文」。
Accept-Encoding: gzip, br 是性能关键:服务器据此把响应体压缩(通常能小 70%),浏览器再解压。现代几乎必开,Nginx 一行 gzip on; 即可。13. RESTful API 设计原则
REST(表述性状态转移)是一种用 HTTP 语义设计 API 的风格。它不是标准,而是约定俗成的最佳实践。
| 动作 | 方法 | URL 示例 | 含义 |
|---|---|---|---|
| 查列表 | GET | /users | 获取用户列表 |
| 查详情 | GET | /users/123 | 获取 id=123 的用户 |
| 新建 | POST | /users | 创建一个用户 |
| 整体更新 | PUT | /users/123 | 替换该用户全部信息 |
| 局部更新 | PATCH | /users/123 | 改该用户的某字段 |
| 删除 | DELETE | /users/123 | 删除该用户 |
13.1 REST 的核心要点
- 资源用名词(URL),不用动词:错误
/getUser,正确GET /users/123。 - 用 HTTP 方法表达动作,而不是把动作写进 URL。
- 无状态:每个请求自带全部信息(如 Token),服务器不依赖上下文。
- 返回合适的状态码:成功 200/201,没权限 403,找不到 404。
- 统一返回结构:如
{ "code":0, "data":{...}, "msg":"ok" },便于前端统一处理。
14. HTTP/2:性能飞跃
HTTP/2(2015)是 HTTP 诞生以来最大的一次架构升级,但对开发者几乎透明——你写代码的方式没变,只是底层快了。
14.1 四大特性
| 特性 | 说明 | 解决的问题 |
|---|---|---|
| 二进制分帧 | 报文不再是文本,而是二进制帧 | 解析更快、更不易出错 |
| 多路复用 | 一个连接上并行交错多个请求/响应 | 队头阻塞、连接数限制 |
| 头部压缩(HPACK) | 头部建索引表,重复字段只传索引 | 头部冗余、带宽浪费 |
| 服务端推送 | 服务器主动把相关资源推给客户端 | 减少往返(现较少用) |
多路复用是 2.0 的杀手锏:以前为加载一个页面要开 6 个连接、还容易排队;现在一个 TCP 连接搞定所有请求,而且互不阻塞。
listen 443 ssl http2; 一行,TLS 证书配好后自动生效。注意:HTTP/2 的「服务端推送」因缓存策略复杂,实际用得不多,部分实现已弃用。15. HTTP/3 与 QUIC:把底层换成 UDP
HTTP/2 解决了应用层的队头阻塞,但传输层(TCP)的队头阻塞还在:一条 TCP 连接里只要有一个包丢失,整条连接都得等它重传,其他请求全卡住。
15.1 QUIC 的思路
HTTP/3 干脆绕过 TCP,直接在 UDP 上实现可靠传输,这就是 QUIC 协议。它把 TCP 的连接管理、拥塞控制、可靠传输重新在用户态实现,并和 TLS 1.3 深度集成。
| 对比 | HTTP/2(TCP) | HTTP/3(QUIC/UDP) |
|---|---|---|
| 传输层 | TCP | UDP + QUIC |
| 队头阻塞 | TCP 层仍存在 | 流之间独立,单流丢包不影响他流 |
| 连接迁移 | 换 IP(如切 Wi-Fi)要重连 | 用连接 ID,切网络不中断 |
| 握手延迟 | TCP+TLS 需多 RTT | QUIC+TLS1.3 可 0-RTT 复用 |
| 部署 | 成熟、普遍 | 较新,需 UDP 443 通、部分中间件不支持 |
16. 为什么需要 TLS:明文传输的三重危险
普通 HTTP 就像明信片:你写的内容,邮递员、分拣员、任何经手人都看得一清二楚。当你连上咖啡厅免费 Wi-Fi,你和设备之间的所有流量都要经过路由器——而路由器主人(或任何能蹭到流量的人)能轻易看到、甚至篡改你发出的东西。
16.1 三大威胁
| 威胁 | 说明 | 惨痛后果 |
|---|---|---|
| 窃听(Eavesdropping) | 攻击者抓包读取明文内容 | 账号密码、聊天记录、Cookie 全泄露 |
| 篡改(Tampering) | 攻击者修改传输中的数据 | 网页被插入广告、恶意脚本、钓鱼链接 |
| 冒充(Spoofing) | 攻击者伪装成目标服务器 | 你以为在登录银行,实际连的是骗子 |
16.2 TLS 如何一一化解
| 威胁 | TLS 的对策 | 用到的技术 |
|---|---|---|
| 窃听 | 加密内容,抓到也看不懂 | 对称加密(AES 等) |
| 篡改 | 校验完整性,被改能发现 | 消息认证码 MAC / AEAD |
| 冒充 | 验证对方身份,确认真服务器 | 数字证书 + 数字签名 + CA |
HTTPS = HTTP + TLS。TLS(Transport Layer Security,传输层安全)就是给 HTTP 这辆明信片邮车装上「加密锁 + 防伪章 + 身份牌」的套件。它工作在 HTTP 之下、TCP 之上,对上层应用透明。
17. 对称加密与非对称加密
加密的本质是:把「明文」用「密钥」变成「密文」,只有掌握钥匙的人能还原。TLS 同时用到了两类加密,各取所长。
17.1 对称加密:同一把钥匙开关锁
加密和解密用同一个密钥(如 AES、ChaCha20)。就像你用一把钥匙锁抽屉,也用同一把钥匙开。
- 优点:速度快、算力低,适合加密大量数据。
- 致命缺点:密钥怎么安全传给对方?如果密钥要通过网络发,那发密钥的过程本身又被窃听了,加密形同虚设——这就是「密钥分发问题」。
17.2 非对称加密:一把锁配两把钥匙
有一对密钥:公钥(public key,公开)和私钥(private key,保密)。用公钥加密的东西,只有对应的私钥能解;用私钥「签名」的东西,任何人用公钥都能验证确是其签署。
- 优点:公钥随便公开,无需保密通道就能分发。
- 缺点:计算慢,不适合加密长内容。
17.3 TLS 的聪明组合:混合加密
TLS 不二选一,而是混合使用:
- 握手阶段用非对称加密安全地协商出一个「会话密钥」。
- 之后通信用这个会话密钥做对称加密传输实际数据。
这样既解决了密钥分发问题(非对称负责安全传密钥),又保证了传输速度(对称负责大量数据)。还能加上数字签名证明服务器身份。后面章节会看到这个组合在握手里的具体舞步。
18. 哈希、消息认证码与数字签名
除了加密,TLS 还需要「完整性校验」和「身份认证」,这依赖三个密码学工具。
18.1 哈希(Hash):数据的指纹
哈希函数把任意长度输入变成固定长度的「摘要」(指纹)。特点:
- 单向:能从原文算摘要,不能从摘要反推原文。
- 唯一性(抗碰撞):原文改一个字,摘要天差地别。
- 常见算法:SHA-256(安全)、MD5/SHA-1(已淘汰,易碰撞)。
echo -n "hello" | sha256sum
# 输出: 2cf24dba5fb0a30e26e83b2ac5b9e29e1b161e5c1fa7425e73043362938b9824
18.2 消息认证码(MAC):防篡改
光加密不能防篡改——攻击者虽看不懂密文,但可以「翻转几位」让解密出乱码。MAC 把「密钥 + 数据」一起哈希,接收方用相同密钥重算比对。不一致就说明被改过。现代 TLS 用 AEAD(如 AES-GCM)把加密和完整性验证合一,更高效。
18.3 数字签名:防冒充 + 防抵赖
数字签名 = 用私钥对数据哈希值加密。验证方用公钥解密出哈希,再自己算一遍数据哈希比对:
- 能对上 → 数据完整且确实来自私钥持有者(认证)。
- 私钥只有持有者才有 → 他无法否认签过(不可否认)。
19. 数字证书与 CA:你怎么相信对方是真的
非对称加密有个漏洞:你拿到的「公钥」真的是目标服务器的吗?中间人完全可以给你一个假公钥,你用假公钥加密,他再用假私钥解密——全程你以为很安全。这就需要数字证书来给公钥「背书」。
19.1 证书是什么
数字证书 = 服务器公钥 + 服务器身份信息(域名、公司等) + 权威机构(CA)的数字签名。它相当于服务器的「网络身份证」,由可信的第三方 CA(Certificate Authority,证书颁发机构)签发。
核心逻辑:你信任 CA,CA 用它的私钥给服务器的公钥「签名担保」。你用预置在系统里的 CA 公钥验证这个签名,签名有效就说明「这把公钥确实属于证书上写的那个域名」。
19.2 证书里有什么
| 字段 | 含义 |
|---|---|
| Subject(主题) | 证书持有者,含 Common Name(域名) |
| Subject Alternative Name (SAN) | 受保护的所有域名(含 www 与裸域) |
| Issuer(颁发者) | 签发它的 CA 名称 |
| Public Key | 服务器公钥 |
| Validity | 有效期(Not Before ~ Not After) |
| Signature | CA 用其私钥对该证书内容的签名 |
| Fingerprint | 证书本身的哈希指纹,用于人工核对 |
20. PKI 体系:信任是怎么传递的
浏览器为什么默认信任某些 CA?因为它出厂时内置了一张信任库(Trust Store),里面列着几百个根 CA 的公钥。这就是 PKI(公钥基础设施)的信任锚。
20.1 证书链(信任链)
CA 也分级别,形成一条证书链:
服务器证书 (Leaf)
↑ 由 中间 CA (Intermediate CA) 签发
↑ 由 根 CA (Root CA) 签发
- 根 CA:自签名,离线保管,极度安全(如 DigiCert、Let's Encrypt 的 ISRG Root)。
- 中间 CA:根 CA 用它去签发大量服务器证书。即使中间 CA 出事,吊销它不影响根。
- 服务器(叶子)证书:你的网站用的证书,由中间 CA 签发。
浏览器验证时一路向上追到信任库里那个根:叶子 ← 中间 ← 根,每一环的签名都有效,且根在信任库内 → 整条链可信。
ssl_certificate 文件里要包含完整链)。只发叶子证书,部分浏览器会因找不到中间 CA 而报「证书路径无效」。21. TLS 1.2 握手流程(详细版)
握手(Handshake)是 TLS 连接建立前的一系列消息交换,目标是:协商加密套件、验证服务器身份、安全生成会话密钥。下面以最经典的 TLS 1.2(RSA 密钥交换)为例拆解。
| 步骤 | 方向 | 消息 | 内容 |
|---|---|---|---|
| 1 | → | ClientHello | 支持的 TLS 版本、密码套件列表、随机数 ClientRandom |
| 2 | ← | ServerHello | 选定的版本与套件、随机数 ServerRandom |
| 3 | ← | Certificate | 服务器证书(含公钥) |
| 4 | ← | ServerHelloDone | 服务器发完了 |
| 5 | → | ClientKeyExchange | 生成 premaster secret,用服务器公钥加密后发送 |
| 6 | ↔ | ChangeCipherSpec + Finished | 双方切换加密,互发校验,握手结束 |
21.1 密钥是怎么算出来的
双方各自独立算出主密钥(Master Secret):
Master Secret = PRF( premaster_secret,
"master secret",
ClientRandom + ServerRandom )
再由主密钥派生出对称加密用的会话密钥。关键点:premaster 用服务器公钥加密传输,中途被截获也解不开(没有私钥)。两端都有 ClientRandom、ServerRandom,加上这个 premaster,就能算出相同的密钥。
22. TLS 1.3 握手:更快更安全
TLS 1.3(2018)是重大升级:砍掉大量老旧、不安全的算法,并把握手压缩到1 个往返(1-RTT),还能0-RTT 恢复连接。
22.1 1-RTT 握手
| 步骤 | 方向 | 消息 | 说明 |
|---|---|---|---|
| 1 | → | ClientHello | 带支持的组、密钥共享参数、随机数和扩展 |
| 2 | ← | ServerHello + 证书 + Finished | 服务器一次性回完,并直接算出密钥 |
| 3 | → | Finished | 客户端确认,之后全加密 |
相比 1.2 的 2 个往返,1.3 省掉了一轮。而且 1.3 强制使用 ECDHE(带前向安全),废除了 RSA、静态 DH、RC4、CBC 等不安全选项。
22.2 0-RTT(零往返)恢复
对于之前连过的服务器,客户端可以在第一个包里就带上应用数据(如 GET 请求),无需等待握手完成。代价是0-RTT 数据不具前向安全且可能重放,只适合幂等请求(如 GET)。
ssl_protocols TLSv1.3; 即可开启(通常和 1.2 共存)。23. 密码套件(Cipher Suite)
密码套件是一串「用什么算法组合来保证安全」的声明,格式如:
TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256
│ │ │ │ └ 校验/PRF 哈希
│ │ │ └ 对称加密算法 (AES-128-GCM)
│ │ └ 身份验证算法 (RSA 证书签名)
│ └ 密钥交换算法 (ECDHE,提供前向安全)
└ 协议
| 环节 | 作用 | 现代推荐 |
|---|---|---|
| 密钥交换 | 协商出共享密钥 | ECDHE(前向安全) |
| 身份验证 | 证明服务器身份 | RSA / ECDSA(配合证书) |
| 对称加密 | 加密实际数据 | AES-128-GCM / AES-256-GCM / ChaCha20-Poly1305 |
| 哈希 | 完整性 / 密钥派生 | SHA-256 及以上 |
ECDHE(前向安全)+ AES-GCM 或 ChaCha20(AEAD 认证加密)+ RSA/ECDSA(证书)+ SHA256(哈希)这套组合就够了。避免包含 CBC、RC4、MD5、SHA-1、NULL 的套件——它们都是历史包袱或明确不安全。24. 前向安全(Forward Secrecy)
前向安全(也叫 PFS,Perfect Forward Secrecy)指:即使服务器长期私钥日后泄露,攻击者也无法解密之前录下的历史通信。
24.1 为什么重要
没有前向安全(如 RSA 密钥交换)时,premaster 是用服务器长期私钥加密的。攻击者把你的流量录下来,等哪天服务器私钥泄露(或被法院强制交出),就能把历史流量全解密——这是多么可怕的事。斯诺登曝光的监控项目正是利用这点大规模留存并解密流量。
24.2 怎么获得前向安全
用临时(Ephemeral)密钥交换:每次握手都生成一对临时的公私钥(ECDHE 里的 E 即 Ephemeral)。会话密钥由临时密钥 + 随机数算出,会话结束临时密钥即销毁。服务器长期私钥只用来签名这次临时公钥,不直接保护 premaster。
| 方式 | 前向安全 | 说明 |
|---|---|---|
| RSA 密钥交换 | ❌ 无 | 长期私钥直接保护 premaster |
| DHE / ECDHE | ✅ 有 | 临时密钥,用完即弃 |
一句话:想安全,握手务必用 ECDHE。这也是为什么 TLS 1.3 直接把它设为唯一可选的密钥交换方式。
25. Nginx HTTPS 完整配置实战
Nginx 是最常用的 Web 服务器/反向代理。下面是一份生产可用的 HTTPS 配置,逐行加了注释。
25.1 单站点 HTTPS 配置
server {
listen 443 ssl; # 监听 443,启用 SSL
listen [::]:443 ssl; # IPv6
server_name www.example.com example.com;
# 证书(必须含完整链:叶子+中间)
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
# 协议与套件:优先 TLS1.3,禁掉老旧协议
ssl_protocols TLSv1.2 TLSv1.3;
ssl_ciphers ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384;
ssl_prefer_server_ciphers off; # 1.3 下由客户端优先
# 会话复用,减少握手开销
ssl_session_cache shared:SSL:10m;
ssl_session_timeout 1d;
ssl_session_tickets off; # 配合前向安全,建议关
# 安全响应头
add_header Strict-Transport-Security "max-age=31536000" always;
add_header X-Content-Type-Options nosniff;
add_header X-Frame-Options SAMEORIGIN;
# 现代加密参数(OCSP 装订)
ssl_stapling on;
ssl_stapling_verify on;
resolver 8.8.8.8 1.1.1.1 valid=300s;
root /var/www/html;
index index.html;
location / { try_files $uri $uri/ =404; }
}
# HTTP 80 端口:强制跳转 HTTPS
server {
listen 80;
server_name www.example.com example.com;
return 301 https://$host$request_uri;
}
sudo nginx -t 检查语法,再 sudo systemctl reload nginx 平滑重载。永远先 -t 再 reload,避免配置写错把全站搞挂。25.2 反向代理 + TLS 终止
常见架构:Nginx 对外做 HTTPS,把请求以 HTTP 转发给后端应用(如 Node/Java/Python),由 Nginx 统一管证书。
server {
listen 443 ssl;
server_name api.example.com;
ssl_certificate /etc/nginx/ssl/fullchain.pem;
ssl_certificate_key /etc/nginx/ssl/privkey.pem;
location / {
proxy_pass http://127.0.0.1:3000; # 转发到本地后端
proxy_set_header Host $host;
proxy_set_header X-Real-IP $remote_addr;
proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for;
proxy_set_header X-Forwarded-Proto $scheme; # 让后端知道原始是 https
}
}
26. Apache HTTPS 配置实战
Apache 通过 mod_ssl 提供 HTTPS。关键是开启 SSLEngine 并指定证书路径。
<VirtualHost *:443>
ServerName www.example.com
DocumentRoot /var/www/html
SSLEngine on
SSLCertificateFile /etc/apache2/ssl/fullchain.pem
SSLCertificateKeyFile /etc/apache2/ssl/privkey.pem
# 若 CA 要求单独的中间证书(较老版本):
# SSLCertificateChainFile /etc/apache2/ssl/chain.pem
# 协议与套件
SSLProtocol all -SSLv3 -TLSv1 -TLSv1.1
SSLCipherSuite ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-RSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384:ECDHE-RSA-AES256-GCM-SHA384
SSLHonorCipherOrder off
# HSTS
Header always set Strict-Transport-Security "max-age=31536000"
</VirtualHost>
# 80 跳转 443
<VirtualHost *:80>
ServerName www.example.com
Redirect permanent / https://www.example.com/
</VirtualHost>
sudo a2enmod ssl rewrite,并 sudo a2ensite 你的站点配置,最后 sudo systemctl reload apache2。27. 申请免费证书:Let's Encrypt + Certbot
以前买证书很贵,现在 Let's Encrypt 提供免费、自动、受信任的证书,配合 Certbot 工具可实现一键申请与自动续期。
27.1 一键申请(Nginx 插件)
# 安装 certbot(Ubuntu 示例)
sudo apt update && sudo apt install certbot python3-certbot-nginx
# 自动申请并修改 Nginx 配置
sudo certbot --nginx -d example.com -d www.example.com
# 纯获取证书(不改配置)
sudo certbot certonly --webroot -w /var/www/html -d example.com
27.2 自动续期
Let's Encrypt 证书有效期仅 90 天,但 Certbot 安装时会加入定时任务自动续期。手动测试:
sudo certbot renew --dry-run # 模拟续期,不真改
sudo certbot renew # 真正续期(到期前30天内才生效)
systemctl status certbot.timer 或 cron)。无数线上事故都是证书悄悄过期导致的——证书过期 = 全站打不开,且浏览器报「不安全」比真被攻击还吓人。27.3 证书文件位置(Certbot)
| 文件 | 路径 | 用途 |
|---|---|---|
| fullchain.pem | /etc/letsencrypt/live/域名/ | 服务器证书+中间证书(给 Nginx 的 ssl_certificate) |
| privkey.pem | 同上 | 私钥(严格保密,权限 600) |
| chain.pem | 同上 | 中间证书链 |
28. 安全加固清单
配通 HTTPS 只是第一步,要做到「安全」还需一系列加固。下面是一份加固检查表。
| 措施 | 作用 | 配置方式 |
|---|---|---|
| HSTS | 强制浏览器只用 HTTPS,防 SSL 剥离 | Strict-Transport-Security: max-age=31536000 |
| 禁旧协议 | 关掉 SSLv3/TLS1.0/1.1 | ssl_protocols TLSv1.2 TLSv1.3; |
| OCSP 装订 | 由服务器代查证书吊销状态,保护隐私、提速 | ssl_stapling on; |
| 安全 Cookie | HttpOnly/Secure/SameSite | 应用层设置(见第 9 章) |
| 隐藏版本 | 不暴露 Server 版本号 | Nginx server_tokens off; |
| CSP | 防 XSS、限制资源加载来源 | Content-Security-Policy: default-src 'self' |
| 证书透明度 | 监控域名被非法签发证书 | Expect-CT / 订阅 CT 日志 |
28.1 HSTS 的「坑」
HSTS 启用后,浏览器在 max-age 期内连 80 端口都不会去,直接内部转 HTTPS。这带来一个风险:一旦你的 HTTPS 挂了,用户在有效期内完全无法访问(连手动输 http 都不行)。所以:
- 先确保 HTTPS 长期稳定,再加 HSTS。
- 初次可设小一点(如
max-age=300)观察,再逐步加大到一年。 - 想进浏览器预加载列表(HSTS Preload)需提交申请,进了就不能轻易撤,慎重。
28.2 用工具验收
配置完去这些网站打分,目标 A 以上:
- SSL Labs(ssllabs.com/ssltest):最权威的 TLS 配置评分。
- securityheaders.com:检查各类安全响应头。
- 命令行
openssl s_client -connect example.com:443:查看证书与握手细节。
29. TLS 性能优化
HTTPS 比 HTTP 多了握手和计算开销,但优化得当几乎无感。下面是关键手段。
| 手段 | 原理 | 收益 |
|---|---|---|
| 启用 TLS 1.3 | 握手 1-RTT、0-RTT 恢复 | 首访更快、重连极快 |
| TLS 会话复用 | Session ID / Session Ticket 复用密钥 | 跳过完整握手 |
| OCSP 装订 | 服务器代查吊销状态 | 省去客户端查 CA 的延迟 |
| HTTP/2 | 多路复用减少连接 | 显著降低延迟 |
| 证书链精简 | 只发必要的中间证书 | 减少握手字节数 |
| 选用 AES-NI / ChaCha20 | 利用硬件加速或移动端友好 | 降低 CPU 开销 |
29.1 会话复用详解
完整握手要 2 个 RTT(1.2)且消耗非对称算力。会话复用让客户端在第二次连接时直接带上上次会话的 ID/票据,服务器认得就跳过密钥协商,回到 1-RTT 甚至 0-RTT。注意:ssl_session_tickets on 会用一个长期密钥加密票据,若追求极致前向安全可关闭(如第 25 章所示)。
30. 案例:把一个纯 HTTP 站点迁移到 HTTPS
这是每个运维/开发者都会遇到的真实任务。下面是一套零停机、不丢 SEO 的迁移流程。
30.1 迁移步骤清单
- 准备证书:用 Certbot 申请(见第 27 章),拿到 fullchain.pem 与 privkey.pem。
- 部署 HTTPS:在 Nginx/Apache 上加 443 监听与证书(见第 25/26 章),先保留 80 端口可访问,不要马上禁。
- 内网自测:用
curl -I https://example.com确认证书有效、内容正常。 - 修复混合内容(Mixed Content):页面里如果有
http://写的图片/JS/CSS,浏览器会拦截它们,导致 HTTPS 页面「不安全」。把内链资源全改成https://或协议相对//。 - 加 80→443 跳转:
return 301 https://$host$request_uri;。 - 加 HSTS:先小
max-age观察,再加大(见第 28 章)。 - 更新外部引用:搜索引擎提交 HTTPS 站点地图(sitemap)、改 CDN/第三方回调地址。
- 监控证书到期:设告警,避免 90 天后悄悄过期。
http:// 的资源。打开开发者工具 Console,它会精确列出哪些资源被拦截,逐个改掉即可。30.2 混合内容示例与修复
// 错误:HTTP 资源在 HTTPS 页面会被拦截
<img src="http://cdn.com/a.png">
<script src="http://cdn.com/b.js"></script>
// 修复:统一 HTTPS,或用协议相对写法(自动跟随当前页协议)
<img src="https://cdn.com/a.png">
<script src="//cdn.com/b.js"></script>
31. 案例:用 Wireshark 抓包看清 HTTP 与 TLS
「眼见为实」。抓包能让你真正看见报文长什么样,是排错和学习的利器。
31.1 抓 HTTP 看明文
- 打开 Wireshark,选正在用的网卡,输入过滤
http。 - 浏览器访问一个 http:// 站点(明文,便于观察)。
- 在包列表里找
GET / HTTP/1.1,右键 → Follow → HTTP Stream,就能看到完整请求和响应明文。
你会亲眼看到:账号、Cookie、路径全是明文——这就是必须上 HTTPS 的理由。
31.2 抓 HTTPS 看加密
访问 https:// 站点,抓到的 TLS 包里只有密文(Application Data),看不到内容。想解密需在浏览器导出 SSLKEYLOG 并让 Wireshark 加载(仅限你自己浏览器的流量,用于学习):
# 设置环境变量(Chrome/Firefox 会写入密钥)
export SSLKEYLOGFILE=/tmp/keylog.txt
# Wireshark: 编辑 → 首选项 → Protocols → TLS → (Pre)-Master-Secret log
31.3 常见抓包排错场景
| 现象 | 可能原因 | 排查 |
|---|---|---|
| 只有 SYN 没 SYN-ACK | 服务器没监听 / 防火墙拦 | 查端口监听、安全组 |
| TLS 握手到 Certificate 后断 | 证书链不完整 / 域名不符 | 用 openssl s_client 看 verify 结果 |
| 握手 Alert 后断开 | 密码套件/协议不匹配 | 双方支持的套件无交集 |
| HTTP 200 但页面白屏 | 前端 JS 报错 / 混合内容 | 看浏览器 Console |
32. 案例:知名安全事件与教训
理解历史漏洞,能帮你避开同样的坑。以下是几个与 HTTP/TLS 相关的经典事件。
| 事件 | 年份 | 问题 | 教训 |
|---|---|---|---|
| 心脏出血 Heartbleed | 2014 | OpenSSL 心跳扩展越界读内存,可泄露私钥/密码 | 及时升级依赖;监控 CVE |
| POODLE | 2014 | SSLv3 的 CBC 缺陷,可降级攻击 | 禁用 SSLv3;防协议降级 |
| SSL 剥离 (SSL Strip) | 2009 | 攻击者把用户 https 请求偷偷降成 http | 部署 HSTS 防止降级 |
| BEAST | 2011 | TLS 1.0 CBC 侧信道攻击 | 升级到 1.2+,用 GCM 模式 |
| 证书误签发 | 多起 | CA 审核不严,给假域名发了真证书 | 用 Certificate Transparency 监控 |
32.1 SSL 剥离攻击详解
这是最该被记住的「日常威胁」:你在咖啡厅连了假 Wi-Fi,攻击者处在你和路由器之间。你输入 example.com,浏览器默认先试 http://,攻击者拦截后自己用 HTTPS 连真服务器,再把明文 http 回给你。你以为连的是 https(其实没加密),账号密码全被截。
防御:HSTS 让浏览器「记住」这个站点必须用 https,连 http 尝试都不做,直接内部跳转——攻击者无从下手。这也是为什么 HSTS 几乎是 HTTPS 站点的必选项。
- 全站 HTTPS + HSTS,挡住 SSL 剥离;
ssl_protocols只留 TLS 1.2/1.3,挡住 POODLE/BEAST;- 密钥交换只用 ECDHE,获得前向安全;
- 用 AEAD 套件(AES-GCM/ChaCha20),避免 CBC 类隐患;
- 订阅 CVE 告警,依赖库(OpenSSL/Nginx)及时升级,避开 Heartbleed 类坑。
33. 互动演示:亲手体会加密与握手
下面这些小工具完全运行在你的浏览器里(纯前端、不联网),点一点就能看到原理。建议边读边玩。
演示 1:凯撒密码(最古老的「加密」)
把字母按固定位数平移。它当然不安全(只有 25 种组合),但能直观展示「加密 = 可逆变换」。
演示 2:XOR 对称加密(现代对称加密的简化版)
把明文每个字节和密钥字节做异或(XOR)。同一个密钥再 XOR 一次就还原——这就是对称加密的核心思想。
演示 3:哈希指纹(SHA-256)
输入任意内容,得到固定 64 位十六进制「指纹」。改一个字,指纹天差地别——这正是数字签名和完整性校验的基础。
演示 4:TLS 1.2 握手分步动画(点击每一步)
点击下方步骤,看客户端与服务器如何一步步协商出密钥并建立加密通道。
演示 5:HTTP 请求构造器
选择方法和填写字段,实时生成对应的原始 HTTP 请求报文(就像浏览器真正发出去的那样)。
34. 术语速查表(Glossary)
| 术语 | 中文 | 一句话解释 |
|---|---|---|
| HTTP | 超文本传输协议 | Web 的「请求—响应」应用层协议 |
| HTTPS | 安全超文本传输协议 | HTTP 跑在 TLS 之上,加密且可认证 |
| TLS / SSL | 传输层安全 / 安全套接层 | 提供加密、完整性、身份验证的协议(SSL 是旧称) |
| TCP | 传输控制协议 | 可靠的、面向连接的传输层协议 |
| UDP | 用户数据报协议 | 不可靠但快,HTTP/3(QUIC) 基于它 |
| URI / URL | 统一资源标识符 / 定位符 | 网址;URL 是 URI 的子集 |
| Method | 请求方法 | GET/POST/PUT/DELETE 等,表意图 |
| Status Code | 状态码 | 三位数字,表请求结果类别 |
| Header | 头部 | 键值对形式的元数据 |
| Cookie / Session | 小纸条 / 账本 | 客户端存 id,服务器存对应数据 |
| Cache | 缓存 | 复用旧响应以减少请求 |
| Symmetric Crypto | 对称加密 | 加解密用同一把密钥(快) |
| Asymmetric Crypto | 非对称加密 | 公钥加密、私钥解密(慢但能安全分发密钥) |
| Hash | 哈希/摘要 | 把任意输入变成固定长度指纹 |
| Digital Signature | 数字签名 | 私钥签名、公钥验证,用于认证与防抵赖 |
| Certificate | 数字证书 | CA 签名的「公钥 + 身份」 |
| CA / PKI | 证书机构 / 公钥基础设施 | 签发并管理证书的信任体系 |
| Cipher Suite | 密码套件 | 密钥交换+认证+对称+哈希 的组合 |
| PFS | 前向安全 | 私钥泄露也不影响历史通信 |
| HSTS | HTTP 严格传输安全 | 强制浏览器只用 HTTPS |
| MITM | 中间人攻击 | 攻击者夹在客户端与服务器之间 |
| OCSP | 在线证书状态协议 | 查询证书是否被吊销 |
| QUIC | 快速 UDP 互联网连接 | HTTP/3 的底层传输协议 |
35. 学习路线与下一步
恭喜你读到这里!下面给一份循序渐进的进阶路线图,方便你按图索骥。
35.1 分阶段学习路径
| 阶段 | 目标 | 建议行动 |
|---|---|---|
| 入门(第 1–8 章) | 搞懂 HTTP 是什么、报文怎么写 | 装个 curl,手动发请求看报文 |
| 进阶(第 9–15 章) | 理解状态保持、缓存、HTTP/2/3 | 用 Chrome DevTools 的 Network 面板逐项观察 |
| 安全基础(第 16–20 章) | 建立加密与证书的心智模型 | 亲手玩第 33 章的演示,再读一遍 |
| 握手深挖(第 21–24 章) | 理解 TLS 握手每一步 | 用 Wireshark 抓一次真实握手 |
| 动手实战(第 25–29 章) | 能独立配置安全 HTTPS | 租个域名+服务器,照着配一遍并跑 SSL Labs 拿 A+ |
| 案例复盘(第 30–32 章) | 把知识用于排错与加固 | 做一遍 HTTP→HTTPS 迁移,处理混合内容 |
35.2 推荐工具
- curl:命令行发 HTTP 请求,调试神器
- Chrome DevTools:看请求、看报文、看缓存
- Wireshark:抓包看 TCP/TLS 真容
- openssl:生成密钥、查看证书、测试握手
- certbot:一键申请 Let's Encrypt 证书
- SSL Labs:TLS 配置评分
- Postman / Hoppscotch:API 调试
- Let's Encrypt:免费证书来源
35.3 常用 openssl 命令速记
# 查看站点证书与握手详情
openssl s_client -connect example.com:443 -servername example.com
# 生成 RSA 私钥
openssl genrsa -out privkey.pem 2048
# 生成证书签名请求 CSR
openssl req -new -key privkey.pem -out csr.pem
# 生成自签名证书(仅测试)
openssl req -x509 -newkey rsa:2048 -nodes -keyout k.pem -out c.pem -days 365
# 计算文件 SHA-256
openssl dgst -sha256 file.zip
本学习材料为 HTTP 与 TLS 入门到进阶的综合性教程,内容基于公开的网络协议标准(RFC 7230/7231、RFC 8446 TLS 1.3、RFC 9000 QUIC 等)与主流工程实践整理。代码示例用于教学演示,生产环境请以官方文档与最新安全建议为准。
© 2026 HTTP·TLS 完全指南 · 一份持续可更新的学习材料