news 2026/9/3 7:04:48

协议与应用基础(三):HTTPS、证书链与中间人攻击

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
协议与应用基础(三):HTTPS、证书链与中间人攻击

协议与应用基础(三):HTTPS、证书链与中间人攻击

    • 前言
    • 一、HTTPS 保护的到底是什么
      • 1.1 HTTPS 的协议栈位置
      • 1.2 HTTPS 的三个核心目标
    • 二、从输入 URL 到 TLS 握手
      • 2.1 DNS 与 HTTPS 的关系
      • 2.2 SNI 和 ALPN
    • 三、X.509 证书到底声明了什么
      • 3.1 证书的抽象模型
      • 3.2 Subject Alternative Name
      • 3.3 Key Usage 与 Extended Key Usage
      • 3.4 有效期、序列号和撤销
    • 四、证书链是怎样建立信任的
      • 4.1 根证书是信任锚
      • 4.2 中间 CA 和终端证书
      • 4.3 为什么服务器通常发送中间证书
      • 4.4 交叉签发与多条路径
    • 五、HTTPS 握手中证书、签名与 ECDHE 的分工
      • 5.1 证书:绑定长期身份公钥
      • 5.2 ECDHE:建立本次会话的共享秘密
      • 5.3 CertificateVerify:证明私钥持有
      • 5.4 Finished:确认双方看到同一个握手
    • 六、中间人攻击是怎样发生的
      • 6.1 裸 DH/ECDH 的中间人攻击
      • 6.2 HTTPS 如何阻止这种攻击
      • 6.3 复制证书不等于复制身份
      • 6.4 伪造域名证书
    • 七、企业 HTTPS 代理为什么能够解密流量
      • 7.1 企业根证书模型
      • 7.2 为什么普通恶意软件不能简单照搬
      • 7.3 证书固定的边界
    • 八、如何排查 HTTPS 证书和中间人问题
      • 8.1 先看当前连接的证书
      • 8.2 浏览器显示证书错误时
      • 8.3 观察证书是否被替换
      • 8.4 CTF 中的常见考点
    • 九、常见误区
      • 9.1 HTTPS 可以隐藏 IP 和域名
      • 9.2 有证书就一定是目标网站
      • 9.3 自签名证书一定不安全
      • 9.4 中间人只能发生在 HTTP 明文连接
      • 9.5 证书固定可以替代所有 PKI
    • 十、总结

前言

HTTPS 并不是一种新的应用层协议,而是 HTTP over TLS:先使用 TLS 建立一条经过认证和加密的连接,再在这条连接上传输 HTTP 请求和响应。

很多人第一次接触 HTTPS 时,会把它简单理解成:

浏览器拿到服务器证书,验证证书,然后把 HTTP 加密起来。

这句话方向没有错,但省略了几个决定安全性的关键问题:

  • 证书链到底验证了什么;
  • 浏览器为什么信任某个 CA;
  • 证书中的域名如何与当前访问地址匹配;
  • TLS 握手中的签名和 ECDHE 分别负责什么;
  • 攻击者如何进行中间人攻击;
  • 为什么“证书签名验证成功”仍然可能不安全;
  • 企业代理、抓包工具和恶意根证书为什么可以解密 HTTPS。

本文以浏览器访问 HTTPS 网站为主线,串起 DNS、TCP、TLS、X.509 证书、证书链、主机名校验和中间人攻击。重点不是记住某个命令,而是理解浏览器究竟在验证什么,以及攻击者必须突破哪些环节才能冒充目标网站。

本文用于学习、授权测试和 CTF 分析。不要在未授权的网络、设备或账号上实施中间人攻击、证书替换或流量解密。

现代密码学 专栏:
https://blog.csdn.net/r_feynman_/category_13190241.html

Crypto 密码解析实战靶场:https://blog.csdn.net/r_feynman_/category_13194584.html


一、HTTPS 保护的到底是什么

1.1 HTTPS 的协议栈位置

访问:

https://example.com/path

通常会经历以下层次:

HTTP ↓ TLS ↓ TCP ↓ IP

HTTP 负责请求和响应语义;TLS 负责身份认证、密钥协商、握手完整性以及应用数据保护;TCP 负责可靠字节流传输。

HTTPS 不是把 HTTP 消息单独加密后发送,而是先建立 TLS 会话,再把 HTTP 字节流交给 TLS 记录层。连接建立后,攻击者通常仍然可以观察:

  • 通信双方的 IP 地址;
  • 连接时间和流量大小;
  • 某些握手元数据;
  • 访问行为的模式。

但在正确配置下,攻击者不能直接读取或修改 HTTP 请求路径、请求头和响应正文。TLS 也不自动隐藏所有流量分析信息。


1.2 HTTPS 的三个核心目标

机密性

网络观察者不能直接读取应用数据:

M → AEAD ⁡ K C M\xrightarrow{\operatorname{AEAD}_K}CMAEADKC

其中K KK是本次 TLS 会话派生出的方向密钥。

完整性

攻击者修改密文、插入记录、删除记录或调整记录顺序时,接收方应检测到错误,而不能把篡改后的内容交给 HTTP 层。

服务器身份认证

客户端不仅要知道“对面有一把私钥”,还要确认这把私钥对应的证书确实被授权给当前访问的域名。

这三者缺一不可。只有机密性没有身份认证,攻击者可以建立自己的加密连接;只有身份认证没有完整性,数据仍可能被篡改;只有完整性没有机密性,消息仍会泄露。


二、从输入 URL 到 TLS 握手

浏览器访问 HTTPS 网站时,可以粗略分成以下阶段:

  1. 解析 URL,确定主机名、端口和路径;
  2. 进行 DNS 解析,得到目标地址;
  3. 建立 TCP 连接,或在现代协议中建立 QUIC 连接;
  4. 发起 TLS ClientHello;
  5. 协商版本、密钥交换组、密码套件和扩展;
  6. 接收并验证服务器证书链;
  7. 验证服务器对当前握手的签名;
  8. 通过 ECDHE 或恢复 PSK 建立握手秘密;
  9. 使用 KDF 派生握手和应用数据密钥;
  10. 发送加密的 HTTP 请求和响应。

HTTPS 安全不是单个证书文件带来的,而是多个阶段共同完成的。DNS 被劫持、主机名校验被关闭、根证书被错误安装、TLS 库版本过旧,都可能改变最终安全结果。


2.1 DNS 与 HTTPS 的关系

DNS 通常负责把域名映射到 IP 地址,但 DNS 本身不等于 HTTPS 身份认证。即使攻击者把example.com解析到了错误的服务器,只要客户端严格验证证书中的名称,伪造服务器仍然不能通过 HTTPS 认证。

反过来,如果客户端关闭证书验证或只验证证书签名而不检查主机名,DNS 劫持就可能直接导向中间人服务。

DNSSEC、DoH 和 DoT 可以改善 DNS 数据的认证或传输隐私,但它们不能替代 TLS 证书验证。不同层次的安全机制应分别理解。


2.2 SNI 和 ALPN

TLS ClientHello 中常见两个扩展:

  • SNI:告诉服务器客户端想访问哪个主机名;一台 IP 上托管多个 HTTPS 站点时,服务器据此选择证书和配置;
  • ALPN:协商应用层协议,例如 HTTP/2 或 HTTP/1.1。

SNI 影响服务器选择证书,但客户端仍然必须验证收到的证书是否匹配目标主机名。ALPN 影响后续应用协议,不应被攻击者静默替换。


三、X.509 证书到底声明了什么

3.1 证书的抽象模型

一张证书可以抽象成:

Cert ⁡ = Sign ⁡ C A _ p r i v a t e ( 身份 , 公钥 , 有效期 , 用途 , 扩展 ) \operatorname{Cert}=\operatorname{Sign}_{CA\_private}(\text{身份},\text{公钥},\text{有效期},\text{用途},\text{扩展})Cert=SignCA_private(身份,公钥,有效期,用途,扩展)

证书签名证明:

  1. TBS(待签名证书)内容没有被篡改;
  2. 签名者拥有对应 CA 私钥。

它不自动证明:

  • 当前连接一定使用了证书对应的私钥;
  • 证书中的组织永远可信;
  • 当前主机名一定被允许;
  • 应用层用户具有某种业务权限。

这些都需要其他验证步骤。


3.2 Subject Alternative Name

浏览器进行主机名验证时,重点检查Subject Alternative Name(SAN)。如果目标是:

https://api.example.com

客户端需要判断该主机名是否匹配证书 SAN 中的 DNS 名称。通配符也有边界,例如:

*.example.com

通常只能匹配一个直接子域名,不能任意匹配a.b.example.com。IP 地址应按照 IP 类型字段进行匹配,不能简单当作普通字符串。

不能只读取证书的Common NameSubject文本就认为主机名验证完成。实际匹配规则还要处理大小写、国际化域名、通配符位置、尾随点和编码规范。


3.3 Key Usage 与 Extended Key Usage

证书中的用途限制同样重要:

  • digitalSignature允许用于数字签名;
  • keyEncipherment与某些密钥加密模式有关;
  • keyAgreement允许密钥协商;
  • keyCertSign表示可用于签发证书;
  • serverAuth表示可用于 TLS 服务器认证;
  • clientAuth表示可用于 TLS 客户端认证。

服务器证书即使链验证成功,如果 EKU 不允许服务器认证,客户端也不应接受它作为普通 HTTPS 服务器证书。


3.4 有效期、序列号和撤销

客户端至少应检查:

N o t B e f o r e ≤ 当前时间 ≤ N o t A f t e r NotBefore\le\text{当前时间}\le NotAfterNotBefore当前时间NotAfter

证书序列号用于签发者区分证书,并用于撤销列表和状态查询。证书没有过期,不代表它没有被撤销;私钥泄露、错误签发、域名控制权变化等情况都可能需要提前撤销。

撤销检查可能通过 CRL、OCSP、OCSP Stapling 或浏览器自有机制完成。不同客户端的策略不完全相同,不能把“当前没有查到撤销信息”简单等同于“证书绝对安全”。


四、证书链是怎样建立信任的

4.1 根证书是信任锚

浏览器和操作系统预先安装一批根 CA 证书。根证书通常是自签名的:

Verify ⁡ R o o t P u b l i c ( Sign ⁡ R o o t P r i v a t e ( T B S ) ) = true \operatorname{Verify}_{RootPublic}(\operatorname{Sign}_{RootPrivate}(TBS))=\text{true}VerifyRootPublic(SignRootPrivate(TBS))=true

但根证书自签名成功并不是它值得信任的原因。信任来自软件发行者、操作系统厂商、企业管理员或用户明确把它加入信任库。


4.2 中间 CA 和终端证书

典型证书链如下:

根 CA ↓ 签发 中间 CA ↓ 签发 网站终端证书

浏览器验证时要完成:

  1. 使用中间 CA 公钥验证网站证书;
  2. 使用根 CA 公钥验证中间 CA 证书;
  3. 检查中间 CA 的CA=truekeyCertSign
  4. 检查路径长度和名称约束;
  5. 检查终端证书的 SAN、EKU、有效期和算法;
  6. 确认链最终落到本地信任锚。

证书链不是“只要找到一个能验签的上级就成功”。每一层都有用途、路径和策略约束。


4.3 为什么服务器通常发送中间证书

客户端通常已经内置根证书,但不一定内置某个网站所需的中间 CA。服务器因此通常发送:

  • 自己的终端证书;
  • 必要的中间 CA 证书;
  • 一般不发送根证书。

如果服务器忘记配置中间链,一些客户端可能无法构建完整路径,从而报告证书链不完整。不同操作系统的缓存和信任库差异可能让问题表现不一致。


4.4 交叉签发与多条路径

同一个 CA 密钥可能存在不同签发路径。客户端可能根据本地信任库、算法策略和证书有效期选择不同链。于是同一网站在不同设备上可能出现不同验证结果。

排查证书链时,不能只看服务器发送的文本顺序,还要确认:

  • 当前候选签发者是谁;
  • 签名验证使用哪把公钥;
  • 哪个根证书成为信任锚;
  • 是否有过期或不再受信的交叉链;
  • 本地信任库是否已经更新。

五、HTTPS 握手中证书、签名与 ECDHE 的分工

5.1 证书:绑定长期身份公钥

证书声明:某个 CA 认可某个身份与公钥之间的绑定:

I D S ⟷ P K S ID_S\longleftrightarrow PK_SIDSPKS

客户端通过证书链、名称和用途检查,决定是否接受这个绑定。


5.2 ECDHE:建立本次会话的共享秘密

服务器和客户端生成临时密钥对:

Q C = [ x C ] G , Q S = [ x S ] G Q_C=[x_C]G,\qquad Q_S=[x_S]GQC=[xC]G,QS=[xS]G

双方计算:

Z = [ x C ] Q S = [ x S ] Q C Z=[x_C]Q_S=[x_S]Q_CZ=[xC]QS=[xS]QC

这个共享秘密用于派生本次会话密钥。它不是证书公钥,也不是长期身份密钥。


5.3 CertificateVerify:证明私钥持有

服务器使用证书对应的长期私钥,对当前握手上下文进行签名:

σ = Sign ⁡ s k S ( context ∥ H ( transcript ) ) \sigma=\operatorname{Sign}_{sk_S}(\text{context}\|H(\text{transcript}))σ=SignskS(contextH(transcript))

客户端用证书中的公钥验证。这样客户端不仅知道“某 CA 签发过一张证书”,还知道当前连接对端确实持有对应私钥。


5.4 Finished:确认双方看到同一个握手

Finished 使用从握手秘密派生的验证密钥,认证当前完整 transcript:

V e r i f y D a t a = MAC ⁡ F i n i s h e d K e y ( H ( transcript ) ) VerifyData=\operatorname{MAC}_{FinishedKey}(H(\text{transcript}))VerifyData=MACFinishedKey(H(transcript))

如果攻击者替换了版本、扩展、临时公钥或证书相关消息,Finished 通常无法验证通过。


六、中间人攻击是怎样发生的

6.1 裸 DH/ECDH 的中间人攻击

假设 Alice 想与 Bob 建立 ECDH。Alice 发送Q A Q_AQA,Bob 发送Q B Q_BQB。如果没有身份认证,Mallory 可以拦截并替换:

Alice Mallory Bob |------ Q_A ---------->| | |<---------------------|--------- Q_M ----------| | | | |<------ Q_M ----------| | | |<--------- Q_B ---------|

结果是:

  • Alice 与 Mallory 计算共享密钥K A M K_{AM}KAM
  • Mallory 与 Bob 计算共享密钥K M B K_{MB}KMB

Mallory 可以解密 Alice 的请求,再用另一把密钥重新加密发给 Bob;Bob 的响应也可以被反向处理。这就是典型的中间人攻击。


6.2 HTTPS 如何阻止这种攻击

HTTPS 使用证书和握手签名把服务器身份绑定到当前握手:

  1. Mallory 发送自己的临时公钥;
  2. Alice 要求 Mallory 提供一个对example.com有效的证书;
  3. Mallory 如果没有受信 CA 签发的合法证书,证书链或 SAN 验证失败;
  4. 即使 Mallory 复制了真实服务器证书文件,也没有对应私钥,无法完成握手签名;
  5. 如果 Mallory 自己签发证书,浏览器默认不信任其根 CA。

因此攻击者必须突破信任链、获得目标私钥、控制客户端信任库,或诱导客户端关闭验证。


6.3 复制证书不等于复制身份

证书是公开材料,攻击者通常可以下载网站证书。真正需要保护的是与证书公钥对应的私钥:

Q = PublicKey ⁡ ( d ) Q=\operatorname{PublicKey}(d)Q=PublicKey(d)

只有掌握d dd,攻击者才能对握手 transcript 生成有效签名。证书文件泄露本身通常不是私钥泄露。


6.4 伪造域名证书

如果攻击者能够骗过 CA 的域名控制验证,就可能获得一个对目标域名有效的证书。客户端此时可能无法仅靠证书签名区分攻击者和真实站点。

这说明 PKI 的安全性不仅依赖数学,还依赖:

  • CA 身份验证流程;
  • 域名控制权保护;
  • 证书透明度和监控;
  • 证书撤销;
  • 私钥保护;
  • 浏览器和操作系统的信任策略。

七、企业 HTTPS 代理为什么能够解密流量

7.1 企业根证书模型

在企业内网、杀毒软件或调试代理中,常见 TLS 检查模式是:

客户端 ←→ 企业代理 ←→ 真实服务器

企业管理员把一个自有根 CA 证书安装到客户端信任库。代理访问真实服务器,再为目标域名动态生成一张由企业根 CA 签发的证书。客户端看到证书链最终连接到自己信任的企业根 CA,因此接受代理。

代理分别与两端建立 TLS 会话:

  • 客户端与代理使用一把会话密钥;
  • 代理与真实服务器使用另一把会话密钥。

代理能够读取和重新加密 HTTP 内容,因此这不是“突破了 TLS 数学”,而是客户端明确把代理根证书纳入信任边界。


7.2 为什么普通恶意软件不能简单照搬

恶意软件若想采用相同方法,必须让客户端信任它的根证书,或者控制浏览器、操作系统、企业配置或应用自带信任库。现代系统会通过:

  • 根证书安装权限;
  • 企业策略;
  • 证书固定或应用级信任;
  • 安全启动和设备管理;
  • 用户提示与审计

限制这种行为。但一旦恶意根 CA 被安装到受信任的信任库中,影响范围可能非常大。


7.3 证书固定的边界

证书固定(pinning)让应用额外期待某个公钥或证书集合,而不是完全依赖系统 CA。它可以降低误签发或企业代理的影响,但也会带来:

  • 证书轮换困难;
  • 密钥泄露后的更新问题;
  • 备份公钥和迁移策略复杂;
  • 错误固定导致线上服务不可用。

不能把固定机制当成所有场景的万能替代方案,应根据应用生命周期和更新能力设计。


八、如何排查 HTTPS 证书和中间人问题

8.1 先看当前连接的证书

授权环境中可以使用:

openssl s_client-connectexample.test:443\\-servernameexample.test-showcerts

重点查看:

  • SubjectIssuer
  • SAN;
  • 有效期;
  • 公钥算法和曲线;
  • KeyUsage、EKU;
  • 服务器发送的中间证书;
  • TLS 版本和密码套件。

命令输出只能帮助观察连接,不能替代应用实际的主机名和策略验证。


8.2 浏览器显示证书错误时

常见错误与含义:

  • 证书过期或尚未生效:系统时间或证书生命周期问题;
  • 名称不匹配:访问域名不在 SAN 允许范围;
  • 证书链不受信:缺少中间证书、根不受信或企业证书未安装;
  • 证书被撤销:证书不应继续使用;
  • 弱算法或密钥:不符合客户端安全策略;
  • 代理证书:当前连接可能经过企业 TLS 检查代理,也可能存在恶意中间人。

不要为了消除警告而直接点击“继续访问”,应先确认连接目标、信任来源和代理环境。


8.3 观察证书是否被替换

可以在不同网络、不同设备和不同时间比较:

  • 证书序列号;
  • 公钥指纹;
  • Issuer;
  • 证书链;
  • SAN 和有效期。

如果企业环境使用合法 TLS 检查,Issuer 通常会变成企业内部 CA;如果是恶意替换,可能出现陌生根 CA、异常有效期或不符合组织策略的签发者。


8.4 CTF 中的常见考点

  • 证书链中给出伪造根或错误中间 CA;
  • 客户端只验证证书签名,不验证 SAN;
  • 客户端信任任意自签名证书;
  • 证书过期但程序忽略时间;
  • 证书与服务器私钥不匹配;
  • 代理替换证书但客户端导入了代理根;
  • 从证书或私钥文件中恢复弱 RSA 参数;
  • TLS 版本或密码套件降级;
  • 应用自带信任库与系统信任库不一致。

排查时应记录程序实际检查的字段,而不是只看浏览器是否显示一个绿色锁图标。


九、常见误区

9.1 HTTPS 可以隐藏 IP 和域名

HTTPS 主要保护应用层内容。IP、连接时间、流量大小以及部分握手信息仍可能暴露。需要额外的网络隐私方案才能减少元数据泄露。

9.2 有证书就一定是目标网站

证书必须进一步检查 SAN、链、有效期、用途和当前连接是否持有对应私钥。证书文件本身可以被任何人复制。

9.3 自签名证书一定不安全

自签名证书没有进入公共浏览器信任体系,但在受控内网、设备配对或显式分发信任指纹的场景中可以安全使用。关键是信任是否通过安全渠道建立,而不是证书是否由公共 CA 签发。

9.4 中间人只能发生在 HTTP 明文连接

即使使用 HTTPS,如果客户端关闭验证、信任恶意根证书、没有做主机名校验或应用协议存在降级路径,仍可能遭受中间人攻击。

9.5 证书固定可以替代所有 PKI

固定机制有适用边界,不能忽略密钥轮换、备份、更新和设备管理。错误固定同样可能造成大面积不可用。


十、总结

HTTPS 的安全主线可以写成:

URL/主机名 → 证书链验证 → 握手签名 → ECDHE → KDF → AEAD HTTP \text{URL/主机名}\rightarrow\text{证书链验证}\rightarrow\text{握手签名}\rightarrow\text{ECDHE}\rightarrow\text{KDF}\rightarrow\text{AEAD HTTP}URL/主机名证书链验证握手签名ECDHEKDFAEAD HTTP

证书链解决“哪个公钥被哪个信任锚认可”;SAN 解决“证书是否对应当前访问的主机名”;CertificateVerify 解决“当前对端是否持有对应私钥”;ECDHE 解决“本次会话如何建立临时共享秘密”;Finished 和 AEAD 解决“握手和应用数据如何保持完整性与机密性”。

中间人攻击通常不是破解 AES 或椭圆曲线,而是利用身份认证缺失、信任库错误、主机名校验缺失、恶意根证书或私钥泄露。理解每个环节的职责,才能判断一次 HTTPS 连接到底保护到了哪里。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/3 7:03:57

基于SnowNLP的微博评论情感分析:从爬虫到可视化的Python实战

简介&#xff1a;这是一份面向Python初学者与NLP入门实践者的新浪微博评论情感分析工具源码包&#xff0c;聚焦中文文本情感判别这一典型NLP应用场景&#xff0c;适用于舆情监控、产品口碑分析、课程设计与毕业实践等需求。压缩包共7个文件&#xff08;4个Python脚本、2个文本配…

作者头像 李华
网站建设 2026/9/3 7:02:21

ChatGPT Plus/Pro订阅指南:解决开发者AI助手使用限制

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/3 7:01:55

信号去噪实战:从低通滤波到维纳滤波的MATLAB实现与对比

简介&#xff1a;本资源是一份面向图像处理初学者与MATLAB实践者的实用代码包&#xff0c;聚焦维纳滤波与低通滤波的核心原理与工程实现&#xff0c;解决图像去噪与复原中的典型问题。压缩包共2个MATLAB脚本文件&#xff08;.m&#xff09;&#xff0c;总大小仅1KB&#xff0c;…

作者头像 李华
网站建设 2026/9/3 7:01:41

线控制动EMB控制器PCB硬件设计:从电源到功能安全的量产级解析

线控制动EMB的拆解&#xff0c;很多人一开始会盯着电机、丝杠和夹紧机构看&#xff0c;但真正决定这个产品能不能从样机走向量产&#xff0c;很大一块功夫在控制器PCB上。这次拆解主要围绕量产级EMB控制器的PCB硬件方案来展开&#xff0c;我会按电源、驱动、信号采样、主控通信…

作者头像 李华
网站建设 2026/9/3 7:00:45

Prometheus 监控 Alertmanager 全栈实战:让告警中枢自身不再沉默

Prometheus 监控 Alertmanager 全栈实战&#xff1a;让告警中枢自身不再沉默Alertmanager 是 Prometheus 生态的告警中枢&#xff0c;负责去重、分组、静默、路由并最终将告警推送到 Email、Slack、PagerDuty 等渠道。一旦它的 通知延迟飙升、推送持续失败、静默规则异常 或 集…

作者头像 李华