CodeRoadMap
首页路线题库资源库文章社区
CodeRoadMap

程序员的学习成长路线图。内容免费开放,登录后可同步路线图与课时进度。

由 程序员柏风 独立维护 · 关于作者

学习

  • 路线图
  • 课程
  • 面试题
  • 文章
  • 我

更多

  • 资源
  • 社区
  • 关于作者
  • 内容说明

© 2026 CodeRoadMap

津ICP备2026012044号-1·津公网安备12011002026155号·coderoadmap@126.com
HTTP 协议与缓存/课时/HTTPS 与 TLS
RawBlame
课时目录12 节

HTTP 协议与缓存

  1. 01HTTP 是什么
  2. 02方法与语义
  3. 03状态码
  4. 04请求与响应头
  5. 05HTTPS 与 TLS
  6. 06HTTP 缓存
  7. 07Cookie 与会话
  8. 08CORS
  9. 09REST 与资源设计
  10. 10HTTP/2 与 HTTP/3
  11. 11应用层缓存对照
  12. 12综合练习

HTTPS 与 TLS

证书、握手直觉、与 nginx-essentials 衔接。

30 分钟

HTTPS 与 TLS

这一课你将能做到

  1. 用三句话说明 HTTPS 相对纯 HTTP 防住了什么:窃听、篡改、冒充,并说出每一条靠 TLS 的哪个机制
  2. 画出「浏览器 ──TLS──► Nginx:443 → 内网明文 → Spring:8080」的链路,解释为什么证书装在 Nginx 而业务仍是明文
  3. 用浏览器锁图标与 curl -v 确认证书域名与 TLS 版本,知道本地自签证书何时用 -k、为什么生产绝不能用

为什么要学

上一课说过:Authorization、Cookie、手机号——在纯 HTTP 上全是明信片,路径上的任何节点(公共 Wi-Fi、运营商、代理)都能读能改。全栈开发的默认共识是「公网必须 HTTPS」,但配了 HTTPS 仍会踩坑:证书过期、混合内容被拦、反代后应用以为自己是 HTTP 导致 Secure Cookie 失效、重定向死循环。

面试必考「HTTPS 握手过程」「对称加密和非对称加密为什么都用」,本课建立 TLS 直觉,证书申请与 Nginx 细节配置交给 nginx-essentials 的 SSL 课。

先建立图像

明文 HTTP 的风险TLS 的对策
旁路窃听 body、Cookie、密码对称加密保护应用数据(密钥只有通信双方知道)
中间人篡改 HTML/JSON/JS完整性校验(AEAD 加密套件自带防篡改)
假站点骗你输密码证书链 + 系统信任的 CA 证明「这公钥真属于该域名」

简化握手直觉(不必背字节序):

1. Client Hello:我支持的 TLS 版本与加密套件列表
2. Server Hello + 证书:选定版本套件,出示证书(含域名与公钥)
3. 客户端校验证书:域名对得上?链条到系统信任的根?没过期?
4. 密钥协商(非对称算法只用来安全地商量出一个对称会话密钥)
5. 之后所有 HTTP 请求/响应都在这条加密通道里飞

为什么对称 + 非对称混用:对称加密快但「密钥怎么安全送到对方」是无解问题;非对称加密能解决传输但太慢。所以非对称只用来协商,对称负责干活。

本站生产拓扑:

浏览器 ──TLS──► Nginx :443(证书装在这里,TLS 在这里结束)
                 ├─ proxy_pass http://127.0.0.1:8080   /api/* → Spring
                 └─ proxy_pass http://127.0.0.1:3000   页面 → 前端服务

TLS 终止在 Nginx:门岗持证,内院 Spring 只监听本机/内网,公网摸不到 8080——内网明文不等于整条链路暴露。

跟着做

步骤 1:看锁与证书

  1. 打开 https://coderoadmap.cn,点地址栏锁图标 → 「连接安全」→ 证书
  2. 记录三项:颁发给(域名/SAN)、颁发者(如 Let's Encrypt R3)、有效期

应看到:域名与地址栏一致、有效期在未来。再随便开一个 http:// 的老站对比——地址栏的「不安全」提示就是在告诉你这层保护缺失。

步骤 2:curl 看协商出的 TLS 版本

curl -vI https://coderoadmap.cn 2>&1 | findstr /i "SSL TLS subject expire"
# Linux/macOS:curl -vI https://coderoadmap.cn 2>&1 | grep -iE "SSL|TLS|subject"

应看到类似 SSL connection using TLSv1.3 的行——TLS 1.3 握手只需 1-RTT,比 1.2 更快更安全。若看到 TLSv1.0/1.1 说明服务端配置过旧,可以提工单了。

步骤 3:本地自签证书 + -k 的正确用法

给本地 Spring Boot 配自签证书(开发调试 HTTPS 接口用):

# keytool 生成自签证书(JDK 自带),密码均为 changeit
keytool -genkeypair -alias local -keyalg RSA -keysize 2048 \
  -storetype PKCS12 -keystore keystore.p12 -validity 365 \
  -dname "CN=localhost" -storepass changeit
# application.yml
server:
  port: 8443
  ssl:
    key-store: classpath:keystore.p12
    key-store-password: changeit
    key-store-type: PKCS12

启动后:

# 自签证书不在系统信任列表,curl 会报证书校验失败
curl -v https://localhost:8443/api/hello
# -k 跳过校验:只证明「端口通」,不证明「连的是真服务器」
curl -vk https://localhost:8443/api/hello

-k 仅限本地自签排错;生产教用户点「高级→继续访问」等于拆掉防冒充防线。

步骤 4:混合内容自检

页面是 https://,却用 http:// 拉脚本/API,浏览器直接拦截。自查方法:

  1. 打开站点任意 HTTPS 页面 → F12 Console,搜 Mixed Content
  2. Network 面板看有无 blocked: 开头的请求

修复原则:页面内资源与 API 全部用相对路径或 https://。新版浏览器还会把 http:// 导航自动升级,但别依赖浏览器的仁慈。

步骤 5:反代后的「我是不是 HTTPS」陷阱

应用若根据 request.isSecure() 生成重定向或决定 Cookie 的 Secure 标志,在 Nginx 反代后会判断错误——外网明明是 HTTPS,应用却以为自己是 HTTP。两处配合修复:

# Nginx 侧:把真实协议传给上游
proxy_set_header X-Forwarded-Proto $scheme;
# Spring 侧:信任 Forwarded 头
server:
  forward-headers-strategy: framework   # 或 native

验证:写一个 @GetMapping("/proto") 返回 request.isSecure() 与 X-Forwarded-Proto 头的值,直连 8080 与走 Nginx 各 curl 一次对比。

步骤 6:301 强制 HTTPS(Nginx 侧)

server {
    listen 80;
    server_name coderoadmap.cn;
    return 301 https://$host$request_uri;   # 永久跳转,状态码课的 301 在这里用上了
}

再用 curl 亲手看一次跳转:

curl -i http://coderoadmap.cn/api/tracks
# 期望:HTTP/1.1 301 + Location: https://...
# 加 -L 让 curl 自动跟随跳转
curl -sIL http://coderoadmap.cn/api/tracks | findstr /i "HTTP Location"

步骤 7:openssl 摘要(可选,便于脚本监控)

echo | openssl s_client -servername coderoadmap.cn -connect coderoadmap.cn:443 2>/dev/null | openssl x509 -noout -subject -dates

输出 subject 与 notAfter 与浏览器锁图标同源,可写进证书过期监控脚本。

讲清楚要点

  1. 因为 TLS 提供机密性与完整性,所以密码、Token、个人信息的传输绝不能走公网明文 HTTP——本地开发可以 HTTP,上线必须 HTTPS,这是行业底线而非建议。
  2. 因为证书证明「公钥属于该域名」,所以证书的域名/SAN 必须覆盖用户实际访问的 host——只签 example.com 却让用户访问 www.example.com 会直接报警。
  3. 因为常见架构在边缘终止 TLS,所以「内网 Spring 是 HTTP」不等于链路裸奔——前提是 8080 端口不映射公网、防火墙只放行本机/内网访问。
  4. 因为非对称加密只负责协商会话密钥,所以 HTTPS 的性能损耗远比想象小——TLS 1.3 一个 RTT 完成握手,配合会话复用,开销集中在首次连接。
  5. 因为 -k/忽略告警关闭的是身份校验,所以它只证明链路可达,不证明对面是谁——自动化脚本、CI 里禁用校验会把中间人风险重新引入。
  6. 因为私钥泄露等于别人可以冒充你的站点,所以证书私钥要当机密管理——权限收敛、不进 Git 仓库、支持快速吊销重签;用 Let's Encrypt 自动续期把人肉操作降到零。

你可能会懵的地方

  1. HTTPS 是不是另一种协议,方法状态码都变了? 完全没变。方法、状态码、头的语义与 HTTP 一致,变的只是下面多了一层 TLS 加密通道——这也是本 track 先讲语义再讲传输的原因。

  2. 为什么不给 Spring 也配证书? 可以(零信任架构里叫 mTLS),但运维成本高。多数站点「边缘终止 + 内网隔离」已够;银行级内网通信才普遍上 mTLS。

  3. 证书过期会怎样? 浏览器大红警告页,curl 直接报 certificate has expired,App 可能拒绝连接。用 acme.sh/certbot 自动续期 + 过期监控是运维基本功——凌晨证书过期导致全站不可用是经典事故。

  4. HSTS 是干什么的? 响应头 Strict-Transport-Security: max-age=31536000; includeSubDomains 让浏览器记住「接下来一年访问本域只许 HTTPS」,即使用户手输 http:// 也内部强制升级。注意:一旦下发且 max-age 很长,回退 HTTP 会很痛苦——先保证全站 HTTPS 稳定,再上 HSTS。

  5. HTTP/2 是不是必须 HTTPS? 浏览器侧几乎总是(明文 h2c 存在但主流浏览器不支持)。所以下一课讲 HTTP/2 时默认你已经有证书。

错法对照

错法问题正解
登录页 HTTPS,表单提交却 POST 到 http://密码在最后一步裸奔,前面加密全白费全站 HTTPS,接口用同源相对路径
生产用自签证书让用户点「继续访问」防冒充形同虚设,还训练用户无视警告公共 CA(Let's Encrypt 免费)签发真证书
以为「有锁」就能防 XSS/SQL 注入TLS 只保护传输层,应用层漏洞照单全收传输安全与应用安全分开治理
把证书私钥提交进 Git 仓库私钥一旦泄露必须紧急吊销重签私钥只在部署机/密钥管理服务;仓库只放 example 配置
反代后不信任 X-Forwarded-Proto应用误判协议:Secure Cookie 失效、重定向死循环Nginx 传头 + Spring forward-headers-strategy 配对

卡点急救

  1. 浏览器报 ERR_CERT_COMMON_NAME_INVALID:证书域名与访问域名不匹配。检查证书 SAN 是否覆盖 www/裸域;用 curl -vI 的 subject 行确认实际下发的证书(可能 Nginx 配了默认 server 的证书)。
  2. 配了 HTTPS 却重定向死循环:典型是「Nginx 80→443 跳转 + 应用内部再判 HTTP 就跳 HTTPS」互相打架。理清唯一跳转点在 Nginx,应用侧信任 X-Forwarded-Proto 后不再自行跳转。
  3. curl 报 SSL certificate problem: unable to get local issuer certificate:本机缺中间证书或系统时间不对。先校对系统时间;企业内网代理会做 SSL 解密,需导入公司根证书或临时 -k(仅诊断)。

面试常问

  • HTTPS 握手过程?对称加密和非对称加密分别用在哪? 客户端发 Client Hello(版本+套件)→ 服务端回 Server Hello + 证书 → 客户端验证证书链与域名 → 双方协商出对称会话密钥 → 之后用对称加密通信。非对称(RSA/ECDHE)只用于验证身份与协商密钥,因为它慢;对称(AES)用于数据传输,因为它快。TLS 1.3 压缩到 1-RTT。

  • 中间人攻击是什么?HTTPS 如何防住? 攻击者拦截通信冒充服务端(或双向冒充),转发并篡改数据。防住的机制:证书由 CA 签名、链式校验到系统信任根,攻击者拿不到可信证书;会话密钥协商保证偷听者也算不出密钥;AEAD 套件保证任何篡改都会被完整性校验发现。

  • 为什么公司内网服务之间还用 HTTP?这样安全吗? TLS 已在边缘终止,内网流量不出机房,攻击面小;全内网上 mTLS 成本高。前提条件:上游端口不暴露公网、安全组/防火墙限制来源。若要求更高,服务网格里做 mTLS。

自测三问

  1. 纯 HTTP 的三类经典风险是什么?HTTPS 分别靠什么机制对应?
  2. 画出本站的 TLS 终止点,说明为什么 Spring 的 8080 可以是明文,需要满足什么前提。
  3. curl -k 什么时候可以用?什么时候绝对不行?为什么?

小结一句话

HTTPS = HTTP 跑在 TLS 上:对称加密防窃听、完整性校验防篡改、证书链防冒充——证书装在 Nginx 边缘,业务仍在内网应用。

延伸

  • MDN:HTTPS
  • MDN:传输层安全协议(TLS)
  • 下一课:HTTP 缓存——加密通道建好了,如何让浏览器根本不重复要:强缓存、协商缓存与 Cache-Control 全家桶。
加载本节练习…
← 上一课请求与响应头下一课 →HTTP 缓存