Skip to content

TLS 1.2、ECDHE 密钥协商与 CA 信任链 ​

回到总览:00 基础知识(Foundations)相关模块:09. 现代移动端网络底座:HTTP/1.1、HTTP/2、HTTP/3(QUIC) 与弱网治理 · 加密与加固逆向:AES-GCM、代码混淆、Root 检测与 Frida

一句话定义 ​

TLS(Transport Layer Security)是在不可信网络上建立加密 + 身份认证 + 完整性通道的协议;在本模块语境下,重点是 TLS 1.2 握手如何用 ECDHE 完成前向安全的密钥协商,以及客户端如何沿着「叶子证书 → 中间证书 → 根 CA」的信任链完成身份认证——它是 HTTPS / gRPC / mTLS 全部上层通信的安全底座。

代码索引 ​

对应 Lab:TLS 1.2 ECDHE 握手与 CA 信任链验证 — 用 openssl s_client -tls1_2 抓握手过程,观察 ServerKeyExchange 与 CipherSuite 协商;亦可 node ecdhe-forward-secrecy.mjs 离线演示前向安全

为什么需要 ​

  • 为什么明文 HTTP 在公网会被轻易窃听与篡改,而 HTTPS 不会?
    • 一句话答:HTTPS 在 TCP 之上叠加 TLS,用非对称协商出一把对称会话密钥加密全量应用数据,且用证书链验证对端身份,窃听者拿不到密钥、篡改也会被 MAC/Tag 拒绝。
  • 为什么很多资料强调「用 ECDHE 而不是纯 RSA 密钥交换」?
    • 一句话答:纯 RSA 密钥交换里会话密钥由客户端用服务器公钥加密发出,服务器私钥一旦泄露,历史流量全部可被解密;ECDHE 是临时(ephemeral) 协商,每次连接换一对临时椭圆曲线密钥,提供前向安全(Forward Secrecy) ,服务器长期私钥泄露也不影响历史会话。
  • 为什么浏览器/系统有时报「您的连接不是私密连接」,即使证书没过期?
    • 一句话答:证书校验是整条链的工程:除了有效期,还要校验域名 SAN 匹配、签发链完整(中间证书不能缺)、根 CA 在信任库、未被吊销(OCSP/CRL) ;任一环节失败都会中断握手。

底层机制 ​

1. TLS 1.2 握手主干(ECDHE + RSA 签名) ​

ECDHE 握手里,服务器用自己长期 RSA(或 ECDSA)证书对「临时公钥参数」做签名,既完成了身份认证,又让密钥协商材料具备前向安全:

  • 可能输出(用 openssl s_client 观察)
    Cipher Suite: ECDHE-RSA-AES128-GCM-SHA256
    Server Temp Key: ECDH, P-256, 256 bits
    Verify return code: 0 (ok)
  • 预期现象:握手前两段是明文(Hello + 证书),从 ClientKeyExchange 之后所有记录均加密;Server Temp Key 显示的是临时椭圆曲线密钥,而非服务器证书里的长期公钥——这正是前向安全的体现。

2. CA 信任链与证书校验 ​

客户端不「认识」每个站点证书,而是信任一小批内置在操作系统/浏览器的根 CA(Root CA) ,由此递归验证:

  • 校验四要素
    1. 链完整:服务器必须把「叶子 + 全部中间证书」都发过来;只发叶子而缺中间,客户端若无缓存就会校验失败。
    2. 签名链可信:从叶子一路向上,每一级的签名都能用上一级公钥验证,最终落到某个内置根 CA。
    3. 域名匹配:证书 SAN(Subject Alternative Name)必须覆盖访问的 host。
    4. 有效期与吊销:当前时间落在 notBefore~notAfter 内,且未出现在 OCSP/CRL 吊销列表。
  • 预期现象:任何一环断裂(自签名根不在信任库、中间证书缺失、SAN 不匹配、已过期/吊销)都会让握手在 CertificateVerify 阶段失败,客户端抛出证书错误而非悄悄降级。

Android / Flutter / Web / Backend 对照 ​

维度AndroidiOSWeb(浏览器)Backend
TLS 实现Conscrypt(基于 BoringSSL)Security.framework / Network.framework各浏览器内置OpenSSL / BoringSSL / Go crypto/tls
信任库系统 + 网络安全性配置(network_security_config.xml 可加自定义 CA)系统 Keychain 信任库;ATS 默认强制 TLS 1.2+内置根 CA 池自管理 CA 包
抓包/中间人需把代理 CA 装进用户/系统信任库并配置允许需安装描述文件并信任浏览器手动信任代理 CA服务端 mTLS 双向校验
典型约束7.0+ 默认不信任用户 CA,除非显式配置ATS 强制前向安全套件HSTS / 证书透明度证书钉扎(Certificate Pinning)

常见场景 ​

  • 双向认证(mTLS) :金融/内部服务除了客户端验服务器,服务器也要求客户端证书。Android 端通常把客户端证书放进 Keystore 通过 SSLContext 注入;Backend 用 ssl_verify_client on; 之类强制校验。
  • 内网自签 CA:测试环境用自签根 CA 签发服务证书,需在客户端信任库显式加入该根(Android 网络安全性配置、后端 ca-certificates),否则校验失败。
  • 抓包联调HTTPS:Charles/Fiddler 的代理 CA 必须安装并被信任,且 Android 7+ 要在 network_security_config.xml 声明 trust-anchors 包含用户 CA,否则只看到 CONNECT 隧道。

常见误配、事故后果与排障 ​

1. 误配:服务器只发了叶子证书,漏发中间证书 ​

  • 现象:部分客户端(尤其移动端)报证书不可信,桌面浏览器却正常——因为浏览器会缓存/补全中间证书,移动端冷启动没有。
  • 排障与修法:用 openssl s_client -showcerts -connect host:443 看返回了几张证书;在服务器(Nginx ssl_trusted_certificate / 负载均衡)补全中间证书链后重试。

2. 事故:用了被弃用的弱套件或旧协议(TLS 1.0/1.1、RC4、3DES、SHA-1 证书) ​

  • 后果:被合规扫描判高危,iOS ATS / 新版 Android 直接拒绝握手,无法联网。
  • 排障与修法:服务端禁用 TLS 1.0/1.1,套件只留 ECDHE-*-AES-GCM / ECDHE-*-CHACHA20,证书签名算法用 SHA-256+;客户端可用 Qualys SSL Labs 评分复核。

3. 误配:证书钉扎(Pinning)写死,证书轮换后全量无法连接 ​

  • 后果:服务器证书正常续期,但客户端钉扎的旧 SPKI 指纹不匹配,集体握手失败。
  • 排障与修法:钉扎时同时预埋「当前 + 下一张备用」公钥指纹,或改为只钉根/中间 CA;证书轮换窗口内保证备用 pin 已随发版生效。

相近概念对比 ​

概念它解决什么不解决什么
RSA 密钥交换简单,用服务器公钥加密会话密钥无前向安全;私钥泄露历史流量可解密
ECDHE 密钥交换前向安全,临时密钥每次不同仍需证书签名来防止中间人伪造临时公钥
证书链校验回答「对面是不是它声称的站点」不保证站点本身业务逻辑安全
对称加密(AES-GCM)会话内高效加密大量数据不参与密钥如何安全协商

对应实验 ​

对应 Lab:TLS 1.2 ECDHE 握手与 CA 信任链验证 — openssl s_client -tls1_2 抓握手报文,识别 CipherSuite、ServerKeyExchange 与临时密钥,验证证书链;或离线跑 node ecdhe-forward-secrecy.mjs 看 ECDHE 前向安全

复习检查题 ​

  1. 同样是 RSA,为什么「RSA 密钥交换」不安全、而「ECDHE + RSA 签名」能提供前向安全? 答:RSA 密钥交换是用服务器长期公钥直接加密会话密钥,长期私钥一旦泄露,历史上所有截获流量都能解密;ECDHE 中服务器长期 RSA 证书只用来签名临时协商出的椭圆曲线公钥参数,真正的会话密钥来自双方临时密钥的 ECDH 运算,临时密钥用完即弃,所以长期私钥泄露也不影响历史会话——这就是前向安全。

  2. 客户端校验一张站点证书,最少要检查哪几件事?为什么只发叶子证书常常失败? 答:至少四件:链完整、签名链可信(落到内置根 CA)、SAN 域名匹配、有效期与未吊销。只发叶子证书缺少中间证书时,客户端手里只有「叶子」和「内置根」,中间这一跳断开了,无法用根公钥直接验证叶子签名(叶子是由中间签的),所以校验失败——这正是很多「浏览器能连、App 连不上」的根因。

  3. 为什么移动端抓 HTTPS 包比浏览器更麻烦? 答:因为 Android 7+ 默认不信任用户安装的 CA,iOS 也必须安装描述文件并手动信任;还要在 App 的网络安全性配置里显式声明信任用户 CA(或后端关校验),否则代理的 MITM 证书通不过校验,只能看到加密隧道。

速记 ​

  • 三件事:加密(对称 AES-GCM)+ 认证(证书链)+ 完整性(Tag/MAC)。
  • 前向安全:靠 ECDHE 临时密钥,不靠服务器长期私钥;长期私钥只用来「签名」临时参数防伪造。
  • 信任链:叶子 ← 中间 ← 根(根内置);漏发中间证书 = 链断 = 握手失败。
  • 四校验:链完整、签名可信、SAN 匹配、未过期/未吊销。

站点构建时间:2026/8/24 23:43:17