Skip to content

HTTPS / TLS 全过程原理

HTTPS 不是“HTTP 加一个证书”这么简单。HTTPS 的核心是 TLS:它要在不可信网络上同时解决四件事:

  1. 防窃听:别人抓包也看不懂内容。
  2. 防篡改:别人改了内容能被发现。
  3. 身份可信:客户端知道自己连的是正确服务器。
  4. 密钥协商:客户端和服务端能安全生成后续通信使用的会话密钥。

如果只知道“HTTPS 更安全”,遇到证书错误、抓包、网关 TLS 终止、双向认证、证书过期、私钥泄露时就会不知道该怎么排查。

学习目标

学完本章要能说清楚:

  1. HTTP 为什么不安全。
  2. TLS 为什么要同时使用证书、非对称能力和对称加密。
  3. 证书链、CA、域名校验分别解决什么。
  4. 一次 HTTPS 请求从 TCP 连接到业务数据传输的全过程。
  5. TLS 握手中会话密钥怎么来的。
  6. 为什么后续业务数据不用 RSA 直接加密。
  7. TLS 终止、双向 TLS、证书过期、证书不匹配怎么排查。

HTTP 为什么不安全

普通 HTTP 明文传输。

mermaid
flowchart TD
    A["客户端发送 HTTP 请求"] --> B["网络链路"]
    B --> C["服务端"]
    D["攻击者抓包"] -.-> B
    D --> E["直接看到 URL、Header、Body"]

风险:

风险说明
窃听登录态、Token、身份证号、报文内容被看到
篡改响应内容或请求参数被中间人改掉
冒充客户端不知道对面的服务器是不是真的
重放攻击者拿到旧请求后重复发送

注意:HTTPS 能保护传输链路,但不自动解决所有业务安全问题。开放 API 仍然可能需要签名、防重放、权限和审计。

TLS 解决问题的总体思路

TLS 不直接用非对称加密传所有业务数据,因为非对称算法慢、加密长度有限。TLS 采用混合方案:

mermaid
flowchart TD
    A["证书体系"] --> B["证明服务端身份"]
    C["密钥协商"] --> D["生成会话密钥"]
    D --> E["对称加密传输业务数据"]
    E --> F["完整性校验防篡改"]

简单理解:

  1. 证书解决“你是谁”。
  2. 密钥协商解决“我们以后用哪把临时密钥说话”。
  3. 对称加密解决“业务数据高效保密传输”。
  4. 完整性校验解决“内容有没有被改”。

证书到底是什么

证书可以理解成 CA 给网站签发的“身份证”。

证书里通常包含:

内容说明
域名证书适用于哪些域名
公钥服务端对应私钥的公钥
颁发者哪个 CA 签发
有效期起止时间
签名算法CA 用什么算法签名
CA 签名证明证书内容没被篡改

浏览器信任证书,不是因为证书自己说可信,而是因为它能沿着证书链追溯到操作系统或浏览器信任的根 CA。

mermaid
flowchart TD
    A["服务器证书 api.example.com"] --> B["中间 CA 证书"]
    B --> C["根 CA 证书"]
    C --> D["浏览器/操作系统信任根证书"]

客户端如何验证证书

客户端收到证书后会检查:

  1. 证书是否过期。
  2. 证书域名是否匹配访问域名。
  3. 证书链是否能连到可信根 CA。
  4. CA 签名是否正确。
  5. 证书是否被吊销。
  6. 证书用途是否允许服务端认证。
mermaid
flowchart TD
    A["收到服务端证书"] --> B{"域名是否匹配?"}
    B -->|"否"| C["证书错误"]
    B -->|"是"| D{"是否过期?"}
    D -->|"是"| C
    D -->|"否"| E{"证书链是否可信?"}
    E -->|"否"| C
    E -->|"是"| F{"CA签名是否正确?"}
    F -->|"否"| C
    F -->|"是"| G["证书校验通过"]

这解释了为什么:

  1. 访问 IP 可能证书不匹配,因为证书签给域名。
  2. 自签证书浏览器不信,因为没有可信 CA 背书。
  3. 证书过期后 HTTPS 会失败。
  4. 中间证书漏配也会导致部分客户端失败。

TLS 握手全过程

下面是简化版 TLS 1.2/1.3 思路。实际细节很多,但学习时先抓主线。

mermaid
sequenceDiagram
    participant C as Client
    participant S as Server
    C->>S: ClientHello 支持的TLS版本、随机数、加密套件
    S->>C: ServerHello 选择版本和套件、随机数
    S->>C: Certificate 服务端证书
    C->>C: 校验证书链、域名、有效期
    C->>S: 密钥协商材料
    C->>C: 计算会话密钥
    S->>S: 计算会话密钥
    C->>S: Finished 握手校验
    S->>C: Finished 握手校验
    C->>S: 使用会话密钥加密HTTP请求
    S->>C: 使用会话密钥加密HTTP响应

重点不是背每个报文字段,而是理解:

  1. 握手阶段建立信任和协商密钥。
  2. 业务阶段使用会话密钥加密 HTTP 数据。
  3. 会话密钥是临时的,不是证书私钥。
  4. 证书私钥泄露会影响身份可信和部分密钥协商安全。

为什么后续业务数据用对称加密

非对称加密的问题:

  1. 计算慢。
  2. 加密数据长度有限。
  3. 不适合大流量业务数据。

对称加密的问题:

  1. 双方要先有同一把密钥。
  2. 密钥不能被攻击者知道。

TLS 把两者组合起来:握手阶段用证书和密钥协商安全地产生会话密钥,后续用对称加密高效传输。

TLS 终止是什么

很多生产系统不是应用服务自己处理 TLS,而是在 Nginx、Ingress、网关或负载均衡处终止 TLS。

mermaid
flowchart TD
    A["浏览器 HTTPS"] --> B["Nginx / Ingress 终止 TLS"]
    B --> C["内部 HTTP 或 HTTPS"]
    C --> D["后端应用"]

TLS 终止表示:

  1. 客户端到网关是 HTTPS。
  2. 网关解密请求。
  3. 网关再把请求转发给后端。

风险和注意点:

  1. 网关到后端如果是 HTTP,内网链路需要可信。
  2. 后端拿到的 scheme 可能是 HTTP,要处理 X-Forwarded-Proto
  3. 证书和私钥集中在网关,权限要严格控制。
  4. 多层代理下真实客户端 IP、协议头要正确透传。

双向 TLS

普通 HTTPS 主要是客户端验证服务端身份。双向 TLS 还要求服务端验证客户端证书。

mermaid
flowchart TD
    A["客户端验证服务端证书"] --> B["服务端身份可信"]
    C["服务端验证客户端证书"] --> D["客户端身份可信"]
    B --> E["建立双向可信通道"]
    D --> E

适合:

  1. 内部服务高安全调用。
  2. 银行、医疗、政务接口。
  3. 设备接入平台。
  4. 不希望只靠 appId/secret 的场景。

代价:

  1. 客户端证书发放和轮换复杂。
  2. 证书吊销和过期管理要求高。
  3. 调试成本比普通 HTTPS 高。

HTTPS 之后还要不要接口签名

要看场景。

HTTPS 保护的是传输链路。它能防止链路窃听和中间人篡改,但开放 API 仍然可能需要业务级签名:

问题HTTPS 是否解决接口签名是否有帮助
传输中被窃听不是主要目标
传输中被篡改也能发现业务报文篡改
调用方身份识别部分,取决于证书/认证
请求被业务层重放不充分timestamp + nonce 有帮助
网关后内部链路审计不一定签名可做业务证据

所以医院开放接口常见组合是:HTTPS + appId + timestamp + nonce + 签名。

Java 客户端证书错误常见原因

错误可能原因
PKIX path building failedJava 信任库不信任证书链
No subject alternative names证书域名和访问域名不匹配
certificate expired证书过期
handshake_failureTLS 版本或加密套件不兼容
bad_certificate双向 TLS 客户端证书不被信任

排查顺序:

  1. 用浏览器或 openssl s_client 看证书链。
  2. 检查访问域名是否在证书 SAN 中。
  3. 检查证书有效期。
  4. 检查服务端是否漏配中间证书。
  5. 检查 Java 运行时信任库。
  6. 检查 TLS 版本和加密套件。

商业场景:医院接口 HTTPS 接入

医疗数据采集平台对接医院接口时,建议:

  1. 对公网或专线 HTTP 接口统一升级 HTTPS。
  2. 证书使用可信 CA,内部系统可使用企业 CA。
  3. 对高安全接口启用双向 TLS。
  4. 网关统一管理证书、协议版本和安全头。
  5. 应用层仍使用签名、防重放和审计。
  6. 证书过期前告警,避免接口中断。

常见坑

后果正确做法
自签证书直接生产使用客户端不信任或被中间人替换使用可信 CA 或企业 CA
证书只签 IP 但用域名访问域名校验失败SAN 包含真实访问域名
中间证书漏配部分客户端握手失败配完整证书链
私钥放代码仓库私钥泄露用 Secret/KMS/网关证书管理
以为 HTTPS 能防所有重放业务旧请求仍可能被重复提交接口层加 timestamp + nonce
证书无过期监控到期当天全站故障证书到期监控和自动续期

面试标准回答

text
HTTPS 的安全核心是 TLS。TLS 握手阶段通过证书链验证服务端身份,并协商出临时会话密钥;后续 HTTP 业务数据用对称加密传输,因为对称加密性能高。证书由 CA 签发,客户端会校验证书链、域名、有效期和签名。HTTPS 解决传输链路的窃听和篡改,但开放 API 仍常常需要 appId、timestamp、nonce 和签名来做业务身份识别、防篡改和防重放。

关联知识点

  1. 加密基础
  2. 开放接口签名与防重放
  3. Spring Security JWT
  4. Nginx HTTPS
  5. K8s Ingress TLS

本章小结

HTTPS/TLS 的主线是:证书证明身份,握手协商会话密钥,对称加密传业务数据,完整性校验防篡改。证书、私钥、域名、信任链、TLS 版本和网关终止都是生产落地必须理解的部分。