英雄联盟证书过期上热搜?吃透 HTTPS 核心:证书、TLS、HTTP3/QUIC 故障复盘全解析

前言

近期笔者亲历两起因 HTTPS 配置不当引发的生产级 P0 故障,另一起更是登上热搜的英雄联盟 SSL 证书过期事件。这些看似 "低级" 的配置问题,却造成了大面积服务不可用,背后折射出的 HTTPS 核心技术盲点值得所有技术人警醒。本文将结合这两起典型故障,拆解 HTTPS 协议、证书、TLS 加密等核心知识点,帮大家理清容易踩坑的关键环节。

故障 1:英雄联盟 SSL 证书过期致全网玩家无法登录

作为全球顶级网游,英雄联盟因 SSL 证书未及时续期,导致大量玩家无法正常登录游戏,故障持续超 10 小时。这一 "低级失误" 引发全网调侃的同时,也让我们意识到:哪怕是头部产品,忽视 HTTPS 证书基础管理也会酿成重大事故。

故障 2:服务端升级 TLS 协议导致客户端请求全量失败

笔者对接的某客户为提升网站安全等级,将服务器加密协议仅保留 TLS 1.3,直接导致我方基于 OkHttp 的客户端请求全部报错,核心异常堆栈如下:

java 复制代码
2026-01-06 01:19:01.204 SGMWH5-qDyCNpxbPkHiMVxV9mA7218NDaw0hI1I [com.xxxx.HttpClientUtils] [ERROR] [3355283]        请求失败
javax.net.ssl.SSLHandshakeException: Received fatal alert: protocol_version
        at sun.security.ssl.Alert.createSSLException(Alert.java:131)
        at sun.security.ssl.Alert.createSSLException(Alert.java:117)
        at sun.security.ssl.TransportContext.fatal(TransportContext.java:357)
        at sun.security.ssl.Alert$AlertConsumer.consume(Alert.java:293)
        at sun.security.ssl.TransportContext.dispatch(TransportContext.java:203)
        at sun.security.ssl.SSLTransport.decode(SSLTransport.java:154)
        at sun.security.ssl.SSLSocketImpl.decode(SSLSocketImpl.java:1290)
        at sun.security.ssl.SSLSocketImpl.readHandshakeRecord(SSLSocketImpl.java:1199)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:401)
        at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java:373)
        at okhttp3.internal.connection.RealConnection.connectTls(RealConnection.java:320)
        at okhttp3.internal.connection.RealConnection.establishProtocol(RealConnection.java:284)
        at okhttp3.internal.connection.RealConnection.connect(RealConnection.java:169)
        at okhttp3.internal.connection.StreamAllocation.findConnection(StreamAllocation.java:257)
        at okhttp3.internal.connection.StreamAllocation.findHealthyConnection(StreamAllocation.java:135)
        at okhttp3.internal.connection.StreamAllocation.newStream(StreamAllocation.java:114)
        at okhttp3.internal.connection.ConnectInterceptor.intercept(ConnectInterceptor.java:42)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.cache.CacheInterceptor.intercept(CacheInterceptor.java:94)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.internal.http.BridgeInterceptor.intercept(BridgeInterceptor.java:93)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RetryAndFollowUpInterceptor.intercept(RetryAndFollowUpInterceptor.java:125)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:147)
        at okhttp3.internal.http.RealInterceptorChain.proceed(RealInterceptorChain.java:121)
        at okhttp3.RealCall.getResponseWithInterceptorChain(RealCall.java:264)
        at okhttp3.RealCall.execute(RealCall.java:93)
...

异常根源清晰指向 "协议版本不兼容":服务端仅开启 TLS 1.3,而我方 OkHttp 客户端默认使用 TLS 1.2 发起请求,最终导致全量请求失败。

故障虽已解决,但背后的技术原理值得深究。不妨先自测以下核心问题的掌握程度:

  1. HTTPS 与 HTTP 的核心区别?HTTP2.0、HTTP3.0 的差异?QUIC 协议是什么?
  2. HTTPS 证书的核心作用?浏览器如何检测证书过期?
  3. TLS 协议的定义?与 SSL 协议的关系?
  4. 如何查看网站的安全等级和证书信息?
  5. OkHttp 客户端默认 SSL 配置?不同 JDK 版本下 OkHttp 的 SSL 配置是否有差异?

接下来,我们逐一拆解这些关键问题。

为什么 HTTPS 必须要有证书?

提到 HTTPS 与 HTTP 的区别,多数人能说出 "端口不同(80 vs 443)""HTTPS 加密传输",但很少有人深究:为何单纯的加密不足以保障安全,必须依赖证书?

如果仅靠 "请求 / 响应加密" 就能解决问题,那么在 HTTP 层面手动加密数据也能实现。但互联网的核心风险并非 "数据窃听",而是 "身份篡改"------ 没有证书,你无法确认访问的网站是否为钓鱼网站;更关键的是,客户端与服务端无法完成安全的密钥协商,最终加密连接也无法建立。

简单来说,HTTPS 证书的核心价值有两点:

  • 身份验证:证明网站的合法身份,防止钓鱼攻击;
  • 密钥协商:为客户端与服务端建立加密连接提供安全的密钥交换机制。

HTTPS 证书的获取与使用

证书的类型

目前主流云厂商(阿里云、腾讯云等)均可申请 HTTPS 证书,按验证等级可分为三类:

  • DV(域名验证型):免费且常用,仅验证域名归属,适合个人 / 小型网站;
  • OV(组织验证型):需验证企业真实身份,适合中小企业;
  • EV(扩展验证型):验证最严格,浏览器地址栏会显示企业名称,适合银行、支付平台等敏感场景。

证书的有效期

  • 免费证书(如 DV 型):有效期通常 90 天,支持自动续签;
  • 付费证书(OV/EV 型):有效期 1-2 年,需手动续签 / 重新申请。

证书过期的影响

有人会问:证书过期后网站仍能访问,仅浏览器提示 "不安全",为何必须续期?核心原因有三:

  1. 密钥协商失败:浏览器 / 客户端与服务器无法协商出安全的加密密钥,传输会退化为明文,数据直接 "裸奔";
  2. 用户信任丧失:浏览器的 "不安全" 提示会导致用户放弃访问;
  3. 客户端请求报错:通过 OkHttp 等工具访问过期证书的网站时,会直接抛出SSLHandshakeException异常(这也是英雄联盟证书过期导致玩家无法登录的核心原因)。

证书申请后,需将.pem.key等格式的证书文件配置到 Nginx、Apache、Tomcat 等 Web 服务器,并开启 TLS 协议支持,才能真正生效。

浏览器如何验证证书合法性?

浏览器并不会内置所有网站的证书,而是通过 "信任链" 机制验证,流程类似 "身份证核验":

  1. 网站向浏览器发送自身证书;
  2. 验证签发机构:检查证书的签发 CA(证书颁发机构)是否在浏览器的信任名单中,排除 "假证书";
  3. 验证证书有效性:确认证书绑定的域名与访问域名一致(防钓鱼)、证书在有效期内(未过期 / 未吊销);
  4. 验证签名完整性:CA 用私钥给证书 "签名",浏览器用内置的 CA 根证书(公钥)验证签名,确保证书未被篡改。

实操技巧:点击浏览器地址栏的🔒图标,即可查看当前网站的证书信息(如有效期、签发机构、加密协议等),如下图所示

Http2.0 Http3.0 与 QUIC 协议

HTTP2.0 和 HTTP3.0 的诞生,均是为了解决 HTTP/1.1 的性能瓶颈,但二者的底层传输协议截然不同 ------HTTP2.0 基于 TCP,HTTP3.0 基于 QUIC。

先明确协议层级:HTTP 属于 OSI 应用层协议,TCP/UDP 属于传输层协议;而 QUIC 协议的层级尚无统一定论,笔者更倾向于归为应用层(因其底层依赖 UDP,且封装了 TCP 的可靠性 + TLS 的加密能力)。

HTTP3.0 使用 QUIC 协议的核心优势

  1. 握手效率提升:合并 TCP 三次握手与 TLS 握手流程,大幅缩短连接建立时间;
  2. 解决队头阻塞:将数据分割为多个独立流,每个流独立传输,彻底解决 TCP 的队头阻塞问题。

这里补充说明下什么叫做 "TCP队头阻塞问题"

TCP 是 "面向连接的可靠传输协议",核心特性是 "按序交付"------ 数据被分割为多个数据包后,服务端必须按发送顺序接收重组。若某个数据包丢失 / 延迟,后续已到达的数据包会被缓存,等待丢失数据包重传完成后再处理,这就是 "队头阻塞"。 在 HTTP2.0 的多路复用场景中,多个请求复用同一个 TCP 连接,只要其中一个帧对应的数据包丢失,整个连接上的所有请求都会被阻塞,直接削弱多路复用的性能优势。

为何 HTTP3.0 尚未全面普及?

尽管 HTTP3.0 性能更优,但国内多数网站仍使用 HTTP2.0(如稀土掘金),核心原因之一是 TLS 协议的兼容性:

  • HTTP3.0 基于 QUIC 协议,而 QUIC 原生要求 TLS 1.3;
  • 部分老旧客户端(如低版本 JDK+OkHttp)不支持 TLS 1.3,强制升级会导致请求失败。

实操技巧 :在 Chrome 控制台执行window.chrome.loadTimes(),查看npnNegotiatedProtocol属性就知道当前网站在使用的是HTTP3还是HTTP2:

  • h2:使用 HTTP2.0;
  • h3:使用 HTTP3.0。

TLS是什么 和 SSL 协议是什么关系

早期教程常将 HTTPS 简化为 "HTTP+SSL",但这一表述现已过时:

  • SSL:由网景公司 1994 年推出,历经 SSL 1.0/2.0/3.0 版本,因存在致命漏洞(如 POODLE 漏洞),2015 年起被主流浏览器 / 服务器全面禁用;
  • TLS:作为 SSL 的替代协议,继承了 SSL 的核心目标,且持续迭代优化(主流版本为 TLS 1.2、TLS 1.3)。

尽管历史原因导致 "SSL 证书" 的说法仍被沿用,但如今 HTTPS 的核心加密协议已是 TLS。

TLS 的核心价值

与 SSL 一致,TLS 主要解决三大问题:

  • 数据加密:避免传输过程中被窃听;
  • 身份验证:配合证书确认通信双方身份;
  • 数据完整性:防止数据被篡改。

在Https现在主流使用的是 TLS 1.3 和 TLS 1.2 两种加密协议,但是由于历史原因很多人仍会说 "SSL 证书",但是实际上SSL已经不再是HTTPS的主流加密协议了

TLS的核心价值和SSL需要解决的问题是一致的,主要有三点: 数据加密(避免传输过程中被窃听)、 身份验证(配合证书确认通信双方身份)、数据完整性(防止数据被篡改)

TLS 1.2 vs TLS 1.3

TLS 1.3 相比 1.2 做了关键优化:

  • 简化握手流程:将 "两次往返" 缩短为 "一次往返",提升 HTTPS 连接建立速度;
  • 移除不安全加密套件:进一步提升安全性。

除此之外TLS和Http的版本也有常用的搭配关系:

HTTP版本 常见搭配TLS版本 备注
HTTP/1.1 TLS 1.2、TLS 1.3 传统HTTPS常用组合,可灵活切换
HTTP/2 TLS 1.2(主流)、TLS 1.3 无强制绑定,支持更高版本TLS
HTTP/3 仅TLS 1.3 HTTP/3基于QUIC协议,QUIC原生内置TLS 1.3加密

这也解释了为何 HTTP3.0 难以快速普及:TLS 1.3 对客户端版本(如 JDK、OkHttp)有严格要求,老旧客户端无法兼容。

使用OkHttp进行Https协议通信的一些细节问题

很多人创建OkHttp客户端在代码里面可能就像这样,简单的只有一行代码:

java 复制代码
OkHttpClient CLIENT = new OkHttpClient.Builder()
        .readTimeout(16, TimeUnit.SECONDS)
        .build();

看似简洁的代码背后,OkHttp 默认做了大量 SSL 配置:

  1. 复用 JVM 默认 SSLContext:JVM 启动时加载系统默认 SSLContext,支持的 TLS 版本取决于 Java 版本;
  2. 加载系统信任证书库:使用操作系统 / JVM 内置的 CA 根证书,可验证绝大多数正规网站证书;
  3. 启用 MODERN_TLS 规范:默认启用 TLS 1.2、TLS 1.3,禁用不安全的 SSL/TLS 版本。

核心坑点:JDK 版本影响 TLS 支持

OkHttp 的默认 SSL 配置依赖 JVM 的 SSLContext,而不同 JDK 版本对 TLS 1.3 的支持不同:

  • Java 8 u261 之前:默认不支持 TLS 1.3;
  • Java 8 u261+:需手动开启 TLS 1.3;
  • Java 11+:默认支持 TLS 1.3。

这也是前文故障 2 的核心原因:服务端仅开启 TLS 1.3,而我方使用的低版本 JDK+OkHttp 默认仅支持 TLS 1.2,最终导致协议版本不兼容报错。

总结

HTTPS 看似是 "加了层加密" 的 HTTP,实则是涉及证书、TLS/SSL、传输协议的复杂体系,任何一个环节的配置疏漏都可能引发生产级故障。结合本文的两起故障与技术拆解,可总结出以下核心结论:

  1. 证书是 HTTPS 的核心基石:不仅是 "加密" 的前提,更是身份验证的关键,证书过期 / 配置错误会直接导致客户端请求失败(而非仅浏览器提示不安全);
  2. TLS 协议是 HTTPS 的加密核心:SSL 已被淘汰,TLS 1.2/1.3 是当前主流,且 TLS 版本直接影响 HTTP 协议的选择(如 HTTP3.0 强制要求 TLS 1.3);
  3. 客户端配置需适配服务端:OkHttp 等客户端的 SSL 配置依赖 JDK 版本,低版本 JDK 可能不支持高版本 TLS,需提前做好兼容性验证;
  4. HTTP3.0 普及仍需时间:尽管性能优势显著,但因 TLS 1.3 的兼容性要求,当前多数网站仍以 HTTP2.0+TLS 1.2 为主;
  5. 基础配置不可忽视:无论是证书续期、TLS 协议配置,还是客户端 SSL 适配,这些看似 "基础" 的操作,却是保障 HTTPS 通信稳定的关键,一旦疏忽就可能酿成 P0 故障。

作为技术人,我们不仅要解决故障,更要理解故障背后的技术原理 ------ 只有吃透 HTTPS 的核心逻辑,才能从根源上避免类似问题的发生。

相关推荐
盖世英雄酱581363 小时前
Java 组长年终总结:靠 AI 提效 50%,25 年搞副业只赚 4k?
后端·程序员·trae
+VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue在线音乐播放系统(源码+数据库+文档)
数据库·vue.js·spring boot·后端·课程设计
code bean4 小时前
Flask图片服务在不同网络接口下的路径解析问题及解决方案
后端·python·flask
+VX:Fegn08954 小时前
计算机毕业设计|基于springboot + vue律师咨询系统(源码+数据库+文档)
java·数据库·vue.js·spring boot·后端·课程设计
努力的小郑4 小时前
2025年度总结:当我在 Cursor 里敲下 Tab 的那一刻,我知道时代变了
前端·后端·ai编程
颜淡慕潇6 小时前
深度解析官方 Spring Boot 稳定版本及 JDK 配套策略
java·后端·架构
Victor3566 小时前
Hibernate(28)Hibernate的级联操作是什么?
后端
Victor3566 小时前
Hibernate(27)Hibernate的查询策略是什么?
后端
superman超哥7 小时前
Rust 内部可变性模式:突破借用规则的受控机制
开发语言·后端·rust·rust内部可变性·借用规则·受控机制
柒.梧.7 小时前
Spring核心知识全解析:从入门实战到进阶
java·后端·spring