- 经常会听说的因为证书过期导致网站无法访问的情况,这里的证书指的是什么证书?
- 证书过期会有什么影响?为什么证书的过期会导致网站无法访问?
证书过期导致网站无法访问的,通常是 SSL/TLS证书(也常叫TLS证书,也是"叶子证书""终端实体证书")
1. 证书过期的影响
- 网站无法正常访问, 最常见到的情况是通过浏览器访问提示"有风险";
- API接口调用失败 :如果是两个后端系统(比如你的App服务器和支付网关)之间用HTTPS通信,其中一方的证书过期了,代码里的安全校验会直接拒绝连接,抛出SSL错误。这会导致整个功能模块瘫痪,比如无法下单、无法登录、数据无法同步;
- 邮件服务异常: 如果Exchange或IMAP/SMTP邮件服务器的TLS证书过期,Outlook、Foxmail等客户端会不停弹窗报错,或者根本连不上服务器,导致无法收发邮件;
- 代码/软件包下载失败: 很多开发工具(如npm, pip, apt)在从仓库下载软件包时,会验证仓库服务器的证书。如果仓库证书过期,
npm install或apt update命令就会直接报错,无法安装或更新任何软件; - 信任链断裂:如果中间CA证书过期(不常见,但会发生),那么它签发的所有网站的SSL证书无法实现验证链而失效。
【提问1】SSL/TLS的叶子证书通常有效期是多长?为什么ssl证书过期会导致服务中断?
- SSL/TLS 叶子证书的最长有效期是 398 天 **(约13个月)。**从2020年底开始实施,是由证书颁发机构浏览器论坛(CA/Browser Forum)制定的行业标准。在此之前,证书有效期可以长达5年甚至更久。之所以不断缩短,主要是为了提高安全性。
- 在TLS握手阶段,会对SSL证书有效期进行校验,过期时按照TLS协议规范会立刻中断握手。
【提问2】证书过期如何导致API调用失败?具体的过程是怎样的?
- 发起连接:API客户端(比如你的Java应用、Python脚本、curl命令)向服务器发起HTTPS请求。
- TLS握手:双方开始协商加密通道。服务器会把自己的SSL证书发给客户端。
- 证书验证 :客户端的TLS库(如OpenSSL、Schannel、BoringSSL)会自动检查证书的有效期 、域名 、签发者等。
- 发现过期 :如果当前时间 > 证书的
notAfter字段,验证失败。 - 中止握手 :客户端按照TLS协议规范(RFC 5246等),必须 拒绝这个证书,并立即发送一个TLS Alert(警告/错误消息),然后关闭连接。
- 抛出异常 :API调用代码收到一个类似
SSLHandshakeException(Java)、SSLError(Python)、certificate has expired(curl)的错误。调用直接失败,不会发送任何实际的业务数据。
【提问3】底层上,是"哪一层的连接"断开了连接?谁执行了断开?
断开的是 TLS会话 ,发生在 TLS握手阶段 。TCP连接可能已经建立,但握手失败后客户端主动发送 TLS Alert + TCP FIN 来断开。
|-----|------------------|-------------|
| 层级 | 组件 | 作用 |
| 应用层 | HTTP / 业务代码 | 发送请求、接收响应 |
| 安全层 | TLS(传输层安全协议) | 加密、证书验证、握手 |
| 传输层 | TCP | 建立可靠连接、数据传输 |
| 网络层 | IP | 路由数据包 |
- **客户端(API调用方)执行的断开操作,**具体过程如下:
- 客户端在验证服务器证书时发现过期;
- 服务器收到Alert和FIN后,也会回应FIN,连接彻底关闭。
- 发送完成后,客户端立即发送 TCP FIN 包,开始关闭连接;
- 客户端通过已建立的TCP连接,把这个Alert消息发给服务器;
- 客户端构造一个 TLS Alert 消息,类型为
certificate_expired(编号 46)。这是TLS协议规定的致命错误(fatal alert);
2. 通过工具curl理解证书过期时发生什么
证书过期时,如果用户通过浏览器访问的时候是可以强行继续访问的,但如果是api接口之间的调用则会直接断开连接,所以会看到关于"服务中断"的新闻,这样的情况往往是api接口之间的调用失败了无法提供服务---交互的客户端因为证书过期而主动中止了TLS握手。(浏览器为用户提供了一个"强行突破"的选项,而API客户端通常没有这个交互界面。)
- 在命令行用curl模拟常规访问:
bash
curl https://expried.badssl.com
-
证书过期时,会看到如下错误
curl: (60) SSL certificate problem: certificate has expired
-
如果加上
-k或--insecure参数(等于手动告诉curl忽略证书错误),就能继续访问:curl -k https://expired.badssl.com/