核验日期:2026 年 11 月 3 日。 本文基于厂商公开安全公告整理。不同 JDK 发行版与证书库策略存在差异;脚本仅用于信息采集,不能直接作为生产环境漏洞判定标准,生产整改请以对应官方安全通告为准。
先记住三个结论:
- 这是证书信任风险,典型后果是连接冒充端点;不能理解为对公网 TLS 端口直接实施 RCE。
- 首次修复存在绕过风险,整改必须同时覆盖 CVE-2026-114820。
- 验收需要同时检查发行版完整构建号、实际信任配置和证书验证行为。
一、事件背景:季度更新刚发布,为什么又有紧急警报?
2026 年 10 月,eMudhra 的部分中间 CA 弱私钥问题,将证书信任风险带到了多个软件生态。根据事件披露页,报告者 Wayne 于 10 月 17 日向浏览器根证书计划团队报告问题,并使用八个中间 CA 对应的私钥对消息签名,证明这些私钥已可被第三方掌握。这与"某个网站证书过期"不同:中间 CA 本身承担签发下级证书的职责,一旦其私钥不再可靠,依赖相应信任路径的客户端就可能接受伪造身份。事件披露与验证材料
风险并不会随着浏览器更新自动从所有应用中消失。浏览器、操作系统、语言运行时与应用可能使用不同的证书库和撤销信息分发机制。即使管理员在浏览器中已看不到异常,独立部署的 Java 运行时仍需按其供应商公告核查;自带证书库的应用也可能需要单独更新。事件影响范围说明
对 Java 运维而言,紧迫感还来自公告的时间顺序:Oracle 于 10 月 20 日发布季度 Critical Patch Update(CPU),次日又发布 CVE-2026-91403 安全警报,列出的受影响版本包括多个当期版本。因此,完成常规 JDK 更新的团队,也需要再次核对本次紧急修复,而不能把"刚升过级"当成安全结论。Oracle 季度 CPU、首次安全警报
10 月 24 日,Oracle 进一步发布 CVE-2026-114820 警报,通过移除相关根证书继续处理风险。本文据此同时讨论首次阻断与后续根信任调整,重点回答三个问题:应用为什么会信错人、实际部署如何排查,以及怎样确认修复真正生效。 后续安全警报
| 项目 | 关键信息 |
|---|---|
| 初次编号 | CVE-2026-91403,2026 年 10 月 21 日 Oracle 发布警报 |
| 后续编号 | CVE-2026-114820,2026 年 10 月 24 日 Oracle 发布警报 |
| 组件与风险 | JSSE 相关证书信任风险,可能造成冒充与通信数据泄露、篡改 |
| Oracle 基础评分 | CVSS v3.1:9.1,保密性与完整性影响高 |
| 修复要求 | 依据供应商公告完成后续修复,并验证实际部署生效 |
1.1 时间线:常规更新之后,仍有紧急更新
| Oracle 公告日期 | 事件 | 运维含义 |
|---|---|---|
| 2026-10-20 | 发布 2026 年 10 月季度 CPU | 完成常规更新后仍需跟进后续警报 |
| 2026-10-21 | 发布 CVE-2026-91403 紧急安全警报 | 不能将前一天的常规更新视为已覆盖本次事件 |
| 2026-10-24 | 发布 CVE-2026-114820 后续警报 | 确认已覆盖根证书移除修复,而非只完成首次阻断 |
日期依据:Oracle 10 月 CPU 修改历史、首次警报、后续警报。这些日期按 Oracle 公告记录列示。常规更新之后仍需持续跟进紧急警报,不能以季度更新完成作为本次事件的验收依据。
1.2 根因:弱私钥,而非 TLS 加密算法被破解
2026 年 10 月 21 日,Oracle 发布 CVE-2026-91403 安全警报,涉及 Java SE 和部分 GraalVM 产品的 JSSE 组件。初次更新对相关中间 CA 证书实施不信任处理。Oracle 首次公告
事件源头是 eMudhra 的部分中间 CA 使用了不安全的密钥。按照 eMudhra 10 月 21 日声明,当年 4 月 30 日密钥生成仪式中的 wrap/unwrap 环节产生了额外的弱密钥,该声明称根因仍在调查。这里引用的是当日说明,不代表调查此后没有进展;公开资料也不支持"攻击者入侵后把私钥出售到黑市"的叙述。eMudhra 官方声明
弱私钥可由公开证书恢复,因此攻击者可能签发伪造证书。八个中间 CA 中,六个用于 TLS,另两个用于代码签名;并非八个都用于网站证书。BellSoft 技术说明
这属于证书信任与身份认证风险,公开资料不支持把它描述为 TLS 报文解析漏洞或可以直接攻击监听端口的远程代码执行漏洞。但"只是信任库问题"同样不意味着风险低:加密仍可正常工作,通信对端却可能是冒充者。
1.3 为什么首次更新还不够
首次修复并不足以封堵风险。Red Hat 明确说明,针对问题中间证书的初次阻断容易绕过,随后上游改为移除相关根 CA,并以 CVE-2026-114820 跟踪。Red Hat 对初次修复的说明
Oracle 于 2026 年 10 月 24 日发布后续警报,说明更新将移除相关根证书。因此,当前整改应覆盖两个 CVE,后续修复不是可选的"纵深防御"。Oracle 后续公告
标题中的"撤销信任"概括了本次事件的完整处置链路:初次编号用于中间证书阻断,后续编号用于根证书移除。不能将两次公告的修复措施混为同一次更新。
需要区分三个概念:
- 中间 CA 证书:可由对端在握手时提供,通常不需要预装在客户端信任库。
- 信任锚 :通常是
cacerts或自定义 truststore 中受信任的根 CA;应用也可能显式信任中间证书等其他证书。 - 证书阻断与撤销信任:对特定证书实施阻断,与从信任库移除根 CA 是不同措施。
因此,"在 cacerts 里找到并删除八张中间 CA 证书"不是可靠的通用操作。它们可能根本不在该文件中;交叉签名还可能提供另一条可验证路径。
二、漏洞原理:证书验证为什么会接受冒充者
典型利用前提:攻击者能够截获或重定向 Java 客户端的连接,并使应用接受通过风险 CA 路径签发的伪造证书。 网络位置、信任锚、证书用途与应用身份验证策略都影响实际可利用性。
真实服务 冒充端点 Java客户端 真实服务 冒充端点 Java客户端 #mermaid-svg-6u6bE3j1LIFCu8Qj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-6u6bE3j1LIFCu8Qj .error-icon{fill:#552222;}#mermaid-svg-6u6bE3j1LIFCu8Qj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-6u6bE3j1LIFCu8Qj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-6u6bE3j1LIFCu8Qj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-6u6bE3j1LIFCu8Qj .marker.cross{stroke:#333333;}#mermaid-svg-6u6bE3j1LIFCu8Qj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-6u6bE3j1LIFCu8Qj p{margin:0;}#mermaid-svg-6u6bE3j1LIFCu8Qj .actor{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-6u6bE3j1LIFCu8Qj text.actor>tspan{fill:black;stroke:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .actor-line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-6u6bE3j1LIFCu8Qj .innerArc{stroke-width:1.5;stroke-dasharray:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .messageLine0{stroke-width:1.5;stroke-dasharray:none;stroke:#333;}#mermaid-svg-6u6bE3j1LIFCu8Qj .messageLine1{stroke-width:1.5;stroke-dasharray:2,2;stroke:#333;}#mermaid-svg-6u6bE3j1LIFCu8Qj #arrowhead path{fill:#333;stroke:#333;}#mermaid-svg-6u6bE3j1LIFCu8Qj .sequenceNumber{fill:white;}#mermaid-svg-6u6bE3j1LIFCu8Qj #sequencenumber{fill:#333;}#mermaid-svg-6u6bE3j1LIFCu8Qj #crosshead path{fill:#333;stroke:#333;}#mermaid-svg-6u6bE3j1LIFCu8Qj .messageText{fill:#333;stroke:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .labelBox{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-6u6bE3j1LIFCu8Qj .labelText,#mermaid-svg-6u6bE3j1LIFCu8Qj .labelText>tspan{fill:black;stroke:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .loopText,#mermaid-svg-6u6bE3j1LIFCu8Qj .loopText>tspan{fill:black;stroke:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .loopLine{stroke-width:2px;stroke-dasharray:2,2;stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);}#mermaid-svg-6u6bE3j1LIFCu8Qj .note{stroke:#aaaa33;fill:#fff5ad;}#mermaid-svg-6u6bE3j1LIFCu8Qj .noteText,#mermaid-svg-6u6bE3j1LIFCu8Qj .noteText>tspan{fill:black;stroke:none;}#mermaid-svg-6u6bE3j1LIFCu8Qj .activation0{fill:#f4f4f4;stroke:#666;}#mermaid-svg-6u6bE3j1LIFCu8Qj .activation1{fill:#f4f4f4;stroke:#666;}#mermaid-svg-6u6bE3j1LIFCu8Qj .activation2{fill:#f4f4f4;stroke:#666;}#mermaid-svg-6u6bE3j1LIFCu8Qj .actorPopupMenu{position:absolute;}#mermaid-svg-6u6bE3j1LIFCu8Qj .actorPopupMenuPanel{position:absolute;fill:#ECECFF;box-shadow:0px 8px 16px 0px rgba(0,0,0,0.2);filter:drop-shadow(3px 5px 2px rgb(0 0 0 / 0.4));}#mermaid-svg-6u6bE3j1LIFCu8Qj .actor-man line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;}#mermaid-svg-6u6bE3j1LIFCu8Qj .actor-man circle,#mermaid-svg-6u6bE3j1LIFCu8Qj line{stroke:hsl(259.6261682243, 59.7765363128%, 87.9019607843%);fill:#ECECFF;stroke-width:2px;}#mermaid-svg-6u6bE3j1LIFCu8Qj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 攻击者能重定向或截获目标连接 若仍信任风险路径,可能接受冒充者 发起TLS连接 返回伪造目标身份的证书链 验证证书链及适用的身份规则 发送业务请求 可另建连接并转发请求 返回响应 转发或篡改响应
攻击者建立的是与客户端的新 TLS 会话;这不等于获得任意既有 TLS 会话的密钥,也不等于能解密历史抓包。能否窃取或篡改业务数据还受应用层加密、签名等机制影响。
2.1 主机名校验为什么仍然不够
正常 HTTPS 校验不能只看"签名验证通过",还涉及有效期、用途、证书约束以及目标主机名等检查。以客户端访问 api.example.com 为例:攻击者若能借助问题 CA 私钥签发包含该域名的伪造证书,域名匹配本身并不能证明签发可信。
这是基于证书认证模型的推导。正确做法是保留主机名校验,同时切断风险信任路径;不能把关闭主机名校验当成修复,也不能把开启主机名校验当成此事件的充分缓解。 JSSE 不同 API 与上层客户端的端点身份验证配置还可能不同,需检查实际应用实现。JSSE 参考
2.2 交叉签名为何影响整改
可以把证书验证理解为寻找一条通往受信任锚点的合规路径。同一个中间 CA 可能存在由不同上级 CA 签发的证书;仅移除一条路径,未必移除了所有可接受路径。
Adoptium 的专项公告明确列出其移除的 emSign ECC Root CA - G3 与 AAA Certificate Services。后者也提醒我们,整改不能只按证书名称是否包含"eMudhra"或"emSign"做字符串筛选,应依供应商证书清单和指纹核对。Adoptium 修复说明
官方资料确认首次修复不足,但本文不推测未由所引资料展开说明的具体绕过机制,也不把交叉签名直接等同于全部绕过原因。
三、CVSS 9.1 分与真实利用条件
Oracle 的 CVSS v3.1 向量为:
CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:N
| 指标 | 取值 | 含义 |
|---|---|---|
| 攻击向量 AV | N | 网络 |
| 攻击复杂度 AC | L | 低 |
| 所需权限 PR | N | 不要求目标应用账号权限 |
| 用户交互 UI | N | 不要求用户交互 |
| 影响范围 S | U | 不变 |
| 保密性 C | H | 高 |
| 完整性 I | H | 高 |
| 可用性 A | N | 无直接可用性影响计分 |
A:N 表示该向量未计入直接可用性影响,不应改写成 A:H;它也不是对所有间接业务后果的保证。CVSS 是标准化基础评分,不能替代对网络位置、信任库和业务配置的环境评估。Oracle 风险矩阵
四、受影响场景:先看实际信任路径
| 场景 | 判断方式 |
|---|---|
| Java 调用 HTTPS API、内部 RPC | 检查实际 TLS Provider、信任锚和证书验证配置 |
| JDBC、LDAP、SMTP、MQ、Redis 等 TLS 连接 | 检查驱动是否使用 JSSE,是否另有专用信任库 |
| Java 仅提供单向 TLS 服务,不验证客户端证书 | 此类 CA 信任问题通常不直接作用于服务端出示自己的证书 |
| 双向 TLS 服务端验证客户端证书 | 需核对客户端证书链、EKU、信任锚及授权规则,不能笼统排除 |
| 只信任经过审查的内部 CA | 若不存在风险公共 CA 路径,此攻击路径可能不适用 |
| 签名 JAR、Java Web Start 等 | 应按供应商指导另外核查,TLS 测试不能覆盖代码签名风险 |
| 纯 HTTP 调用 | 不涉及该 TLS 信任路径,但自身没有 TLS 的保护 |
"Java 是服务端"不足以判断安全,因为同一进程也可能作为客户端访问下游。反过来,也不能断言所有内部 TLS 调用都受影响:只使用内部 CA 的信任体系与默认公共 CA 信任体系不同。
内网身份不构成免疫条件,但中间人攻击仍需要实际的连接截获或重定向能力。"无需应用账号"不等于"没有利用前提"。
4.1 双向 TLS 与代码签名:分别判断
mTLS 包含客户端验证服务端、服务端验证客户端两个方向。内部客户端证书只链到独立私有 CA,并不自动说明同一进程的出站 HTTPS 也只信任私有 CA;应对两个方向分别核查信任配置、证书用途和身份授权。
代码签名风险也不能泛化为"所有 JAR 都会被攻击"。需要关注实际依赖相关签名证书链作出信任决策的部署或验证流程。普通应用通过 classpath 加载依赖,并不意味着 JDK 自动完成了供应商身份授权;下载链路安全与制品签名验证是两个独立检查点。
4.2 构建机同样需要排查
基于上述攻击模型,排查范围还应包含运行 Maven、Gradle 或 Java 构建代理的 CI 节点。如果下载依赖的实际 TLS 客户端仍接受风险信任路径,且连接被截获或重定向,就可能面临仓库冒充及构建输入被篡改的风险。这是场景推导,不代表已发现此类供应链攻击;具体后果还取决于独立的制品签名、可信校验和及仓库策略。
Maven 在构建机上使用的 Java 可能不同于生产 JRE,可先用 mvn -version 核对,再确认实际传输实现及信任配置。对于使用 Wagon HTTP 的环境,不应为绕过更新后的证书错误而启用宽松验证,例如 maven.wagon.http.ssl.insecure=true。其具体作用以 Maven Wagon HTTP 官方文档为准,不能将这些属性套用于全部 Maven 传输实现。
Docker 镜像拉取应沿实际执行拉取的客户端、守护进程或构建器核查,不能仅因构建任务由 Java 编排,就把镜像拉取归为 JSSE 连接。
五、排查方法:从实际进程到信任库
5.1 公告中的"受影响版本"不等于"修复基线"
Oracle 首次公告把 8u511、11.0.33、17.0.21、21.0.13、25.0.5、27.0.1 列在 Affected Products and Versions 中,不能写成"这些版本及以上均修复"。其后续公告还将 8u511-b32 和多个 .0.2 构建列为受影响版本。只读取版本前三段的脚本无法区分这些更新。首次公告、后续公告
同一上游版本的不同发行版可以使用不同的证书数据和补丁,因此不应推出"Oracle 8u511 与所有 OpenJDK 8u512 是同一补丁"或"OpenJDK 8u511 必然不安全"。
5.2 已核验的发行版示例
下表是特定公告中的修复发布示例,不是跨厂商的统一比较规则。部署前仍需检查对应平台、包渠道、构建号与后续公告。
| 发行版或渠道 | 官方公告中的修复示例 | 依据 |
|---|---|---|
| Oracle JDK | 使用官方当前提供、明确覆盖后续 CVE 的更新;本表不以受影响版本反推修复号 | 处置入口 |
| Eclipse Temurin | 17.0.21+9、21.0.13+9、25.0.5+8、27.0.1.0.2+1 | Adoptium 专项公告 |
| BellSoft Liberica | 8u513+9、11.0.33.0.3+7、17.0.21.0.3+5、21.0.13.0.3+5、25.0.5.0.3+5、27.0.1.0.3+5 | BELL-SA-2026-11 |
| Amazon Linux 2 Corretto 8 Extra | java-1.8.0-amazon-corretto-1.8.0_512.b09-1.amzn2 |
ALAS2CORRETTO8-2026-027 |
| RHEL 的 OpenJDK RPM | 依赖系统 ca-certificates,需更新该包;单独发行的 Red Hat build of OpenJDK 自带证书库,另行更新 |
Red Hat 产品说明 |
Adoptium 10 月 27 日专项公告对 JDK 8、11 的状态仍标为等待上游标签,本文不据此推断 11 月 3 日仍未发布;请查对应发布渠道。Temurin 的信任库来自 Mozilla 数据,不能照搬 Oracle 的证书别名与判定规则。
云平台公告中的版本只适用于该产品指定的运行时与渠道,不能外推为所有 OpenJDK 的通用基线。本文未将无法核验的阿里云 SAE 版本说法纳入修复表。
5.3 确认真正运行的 Java
检查业务进程使用的可执行文件、java.home、发行商、完整运行时版本、包版本与镜像摘要。命令行 PATH 中的 java 可能与 systemd、应用服务器、IDE 或容器实际使用的运行时不同。
在支持 jcmd 的 HotSpot 环境,可用同机、同有效用户及组身份执行诊断。先用 jcmd <PID> help 确认命令可用,再核对以下信息:
bash
# 把示例 PID 改为目标业务进程;使用与目标兼容的诊断工具
jcmd 12345 VM.version
jcmd 12345 VM.system_properties |
awk '/^(java.home|java.vendor|java.runtime.version|java.version|javax.net.ssl.trustStore|javax.net.ssl.trustStoreType|javax.net.ssl.trustStoreProvider)=(.*)$/ {print}'
这比查看 PATH 中的另一套 Java 更接近实际进程,但仍不能证明应用最终使用了哪一个 TrustManager。Attach 被禁用、JRE 镜像未携带诊断工具或容器命名空间不同,都可能使命令失败;失败本身不说明有无漏洞。容器内应在正确的 PID 与文件系统视图中核查。jcmd 官方文档
以上仅筛选必要属性,不主动输出密码属性。不要将未经检查的完整系统属性或启动命令复制到公开文章、工单和日志平台。
5.4 确认实际信任来源
默认 JSSE 信任管理器的查找与配置规则,应以所用 JDK 文档为准。重点检查:
javax.net.ssl.trustStore是否指定了外部文件,并检查独立的trustStoreType、trustStoreProvider配置;使用非文件存储时按对应 Provider 核查。- 默认安全目录中是否存在优先使用的
jssecacerts,否则才检查cacerts。 - 应用、框架、驱动是否构建了自己的
SSLContext或TrustManager。 - JDK 的证书文件是否链接或派生自系统 CA 包,容器中是否另行复制了旧文件。
先区分 truststore 与 keystore 的角色: truststore 用于决定信任哪些对端;keystore 常用于提供本机证书及私钥。两者都可以使用 JKS 或 PKCS12 等格式,同一文件也可能承载两类用途,不能根据文件后缀判断角色。javax.net.ssl.keyStore 与 javax.net.ssl.trustStore 不是同一个配置项。
对于使用默认机制、未由应用重写信任管理逻辑的 SunJSSE,默认查找可概括为:显式配置的 truststore → 未显式配置时查找 jssecacerts → 再查找 cacerts。这不是把三份证书库自动合并,也不是任意自定义客户端都遵循的规则。显式指定文件不存在时,不能指望自动回退到新版 cacerts。
默认路径常见为 JDK 8 的 $JAVA_HOME/jre/lib/security/,JDK 11 及以后为 $JAVA_HOME/lib/security/;独立 JRE、供应商打包及系统集成方式可能不同。JSSE 官方参考
keytool -list -v -keystore /实际路径/truststore 可辅助查看证书,但需按可信公告中的 SHA-256 指纹及发行版规则核对。仅搜索名称、看不到八张中间证书,或发现阻断文件存在,都不能证明整改完成。keytool -printcert -jarfile 查看的是签名 JAR 的证书,不是检查运行时信任库的通用方法。
5.5 同机其他 TLS 工具:按信任来源逐项核查
本次 CA 事件的治理范围不限于 Java。Red Hat 专项通告说明了系统证书包及其他生态的相关更新。但 curl、Python、代理和包管理器并不必然使用同一份系统证书库:它们可能读取系统 CA、应用自带 CA bundle、显式指定的文件或容器内独立配置。
因此,应核查每类工具实际使用的证书来源及厂商更新状态。只升级 Java 不一定覆盖其他客户端,更新宿主机 CA 也不一定覆盖自带证书的应用。不能将"更新 JDK 与系统证书库"当成所有环境通用的充分条件。
5.6 验证"危险链拒绝、正常链成功"
使用实际业务运行时、Provider 和信任配置,在受控测试环境验证风险证书链被拒绝,同时正常下游连接成功。不能只把网络超时、DNS 失败或任意握手错误当成阻断成功;应确认失败发生于预期的证书校验环节。
Oracle 提供 CheckCerts.java 辅助检查。Adoptium 特别说明,该工具对根证书的判定与 Temurin 的 Mozilla 信任策略存在差异:不能因为它报告保留的 emSign Root CA - G1 就直接认定 Temurin 未修复。Oracle 检查入口、Temurin 验证说明
5.7 建议使用的验收矩阵
| 验证项 | 合格证据 | 不能代替它的现象 |
|---|---|---|
| 修复来源 | 具体供应商公告与对应安装包或镜像构建 | 只写"已升到最新版" |
| 进程生效 | 实际进程版本、启动配置和部署产物匹配 | 管理员终端的 java -version |
| 风险链拒绝 | 适用的风险测试链在证书验证阶段被拒绝 | DNS 失败、超时、代理拦截页面 |
| 正常链通过 | 真实业务下游的 TLS 与业务请求回归成功 | 只测试一个无关公共网站 |
| 路径完整 | 覆盖实际可用的相关交叉签名路径 | 单个测试站点失败 |
| 特殊用途 | 适用时单独核查代码签名与 mTLS 验证 | 一次出站 HTTPS 测试 |
测试结果必须归属于被测组件。 在浏览器里打开测试页面,不能证明 Java 客户端安全;使用 curl 测试,也不能证明另一个 JDK 安全。如果存在 TLS 检查代理,客户端可能只见到企业代理重新签发的证书,应分别核查代理至目标、客户端至代理两段链路。
测试应建立新的 TLS 连接;既有连接池与可恢复的 TLS 会话不适合作为新信任策略生效的唯一证据。重启或按产品能力明确重建连接及安全上下文后再验证。相关测试证书、代理结果与非浏览器客户端差异可参见事件披露与测试说明。
需要定位原因时,可在受控回归环境对 SunJSSE 临时使用 -Djavax.net.debug=ssl,handshake,trustmanager。日志有助于查看证书和信任管理过程,但输出格式随 JDK 变化、可能包含内部主机与证书信息,不宜无差别长期启用。仅有 PKIX path building failed 也不能证明恰好命中了本次修复,需要结合具体链、锚点及异常原因。JSSE 调试文档
六、信息采集脚本:保留证据,不自动判定
下面脚本只采集指定 Java 的信息,不输出"已修复"或"存在漏洞"的自动结论。参数可指定业务使用的 Java 可执行文件;它不连接测试网站、不修改信任库。
bash
#!/usr/bin/env bash
set -euo pipefail
java_bin="${1:-java}"
if ! command -v "$java_bin" >/dev/null 2>&1; then
printf '[ERROR] 找不到 Java: %s\n' "$java_bin" >&2
exit 1
fi
printf 'Java 命令: %s\n' "$(command -v "$java_bin")"
"$java_bin" -version 2>&1
printf '\n运行时属性:\n'
"$java_bin" -XshowSettings:properties -version 2>&1 |
awk '/^[[:space:]]*(java.home|java.vendor|java.runtime.version|java.version)[[:space:]]*=/ {print}'
printf '\n[REVIEW] 请结合发行版安全公告、实际信任库和验证结果判定。\n'
脚本边界: 不枚举运行中的 JVM、容器或机器上的其他 JDK,不解析业务启动参数,不读取 truststore,也不检测 CVE-2026-114820。输出中的命令路径不一定是符号链接的最终目标。必须先确认传入的可执行文件与业务进程一致,再对照对应发行版公告。
将脚本保存为 collect-java-info.sh 后,可在已确认的业务运行环境中执行:
bash
bash collect-java-info.sh /opt/business-jdk/bin/java
示例路径需要替换为实际可执行文件。即使传入了业务安装目录,也不代表已经识别运行中进程的动态属性;进程核对与信任配置检查仍须分别完成。
七、修复与缓解
7.1 首选:供应商更新并验证生效
安装明确覆盖后续修复的受支持运行时或证书包;容器需更新基础镜像、重建并重新部署。检查挂载的外部 truststore、应用自带 JRE、CI 构建环境及历史镜像,避免更新被旧文件覆盖。
随后重启受影响进程,使新运行时和信任配置加载,核对进程实际版本并回归下游 TLS 连接。只执行一次 java -version 不足以验收。"升级 JDK 是唯一根治"也不准确:对依赖系统 CA 包的发行版,更新相关证书包可能才是关键动作。
7.2 修复决策流程
#mermaid-svg-K303n3wDcVoolvtj{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;fill:#333;}@keyframes edge-animation-frame{from{stroke-dashoffset:0;}}@keyframes dash{to{stroke-dashoffset:0;}}#mermaid-svg-K303n3wDcVoolvtj .edge-animation-slow{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 50s linear infinite;stroke-linecap:round;}#mermaid-svg-K303n3wDcVoolvtj .edge-animation-fast{stroke-dasharray:9,5!important;stroke-dashoffset:900;animation:dash 20s linear infinite;stroke-linecap:round;}#mermaid-svg-K303n3wDcVoolvtj .error-icon{fill:#552222;}#mermaid-svg-K303n3wDcVoolvtj .error-text{fill:#552222;stroke:#552222;}#mermaid-svg-K303n3wDcVoolvtj .edge-thickness-normal{stroke-width:1px;}#mermaid-svg-K303n3wDcVoolvtj .edge-thickness-thick{stroke-width:3.5px;}#mermaid-svg-K303n3wDcVoolvtj .edge-pattern-solid{stroke-dasharray:0;}#mermaid-svg-K303n3wDcVoolvtj .edge-thickness-invisible{stroke-width:0;fill:none;}#mermaid-svg-K303n3wDcVoolvtj .edge-pattern-dashed{stroke-dasharray:3;}#mermaid-svg-K303n3wDcVoolvtj .edge-pattern-dotted{stroke-dasharray:2;}#mermaid-svg-K303n3wDcVoolvtj .marker{fill:#333333;stroke:#333333;}#mermaid-svg-K303n3wDcVoolvtj .marker.cross{stroke:#333333;}#mermaid-svg-K303n3wDcVoolvtj svg{font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:16px;}#mermaid-svg-K303n3wDcVoolvtj p{margin:0;}#mermaid-svg-K303n3wDcVoolvtj .label{font-family:"trebuchet ms",verdana,arial,sans-serif;color:#333;}#mermaid-svg-K303n3wDcVoolvtj .cluster-label text{fill:#333;}#mermaid-svg-K303n3wDcVoolvtj .cluster-label span{color:#333;}#mermaid-svg-K303n3wDcVoolvtj .cluster-label span p{background-color:transparent;}#mermaid-svg-K303n3wDcVoolvtj .label text,#mermaid-svg-K303n3wDcVoolvtj span{fill:#333;color:#333;}#mermaid-svg-K303n3wDcVoolvtj .node rect,#mermaid-svg-K303n3wDcVoolvtj .node circle,#mermaid-svg-K303n3wDcVoolvtj .node ellipse,#mermaid-svg-K303n3wDcVoolvtj .node polygon,#mermaid-svg-K303n3wDcVoolvtj .node path{fill:#ECECFF;stroke:#9370DB;stroke-width:1px;}#mermaid-svg-K303n3wDcVoolvtj .rough-node .label text,#mermaid-svg-K303n3wDcVoolvtj .node .label text,#mermaid-svg-K303n3wDcVoolvtj .image-shape .label,#mermaid-svg-K303n3wDcVoolvtj .icon-shape .label{text-anchor:middle;}#mermaid-svg-K303n3wDcVoolvtj .node .katex path{fill:#000;stroke:#000;stroke-width:1px;}#mermaid-svg-K303n3wDcVoolvtj .rough-node .label,#mermaid-svg-K303n3wDcVoolvtj .node .label,#mermaid-svg-K303n3wDcVoolvtj .image-shape .label,#mermaid-svg-K303n3wDcVoolvtj .icon-shape .label{text-align:center;}#mermaid-svg-K303n3wDcVoolvtj .node.clickable{cursor:pointer;}#mermaid-svg-K303n3wDcVoolvtj .root .anchor path{fill:#333333!important;stroke-width:0;stroke:#333333;}#mermaid-svg-K303n3wDcVoolvtj .arrowheadPath{fill:#333333;}#mermaid-svg-K303n3wDcVoolvtj .edgePath .path{stroke:#333333;stroke-width:2.0px;}#mermaid-svg-K303n3wDcVoolvtj .flowchart-link{stroke:#333333;fill:none;}#mermaid-svg-K303n3wDcVoolvtj .edgeLabel{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K303n3wDcVoolvtj .edgeLabel p{background-color:rgba(232,232,232, 0.8);}#mermaid-svg-K303n3wDcVoolvtj .edgeLabel rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K303n3wDcVoolvtj .labelBkg{background-color:rgba(232, 232, 232, 0.5);}#mermaid-svg-K303n3wDcVoolvtj .cluster rect{fill:#ffffde;stroke:#aaaa33;stroke-width:1px;}#mermaid-svg-K303n3wDcVoolvtj .cluster text{fill:#333;}#mermaid-svg-K303n3wDcVoolvtj .cluster span{color:#333;}#mermaid-svg-K303n3wDcVoolvtj div.mermaidTooltip{position:absolute;text-align:center;max-width:200px;padding:2px;font-family:"trebuchet ms",verdana,arial,sans-serif;font-size:12px;background:hsl(80, 100%, 96.2745098039%);border:1px solid #aaaa33;border-radius:2px;pointer-events:none;z-index:100;}#mermaid-svg-K303n3wDcVoolvtj .flowchartTitleText{text-anchor:middle;font-size:18px;fill:#333;}#mermaid-svg-K303n3wDcVoolvtj rect.text{fill:none;stroke-width:0;}#mermaid-svg-K303n3wDcVoolvtj .icon-shape,#mermaid-svg-K303n3wDcVoolvtj .image-shape{background-color:rgba(232,232,232, 0.8);text-align:center;}#mermaid-svg-K303n3wDcVoolvtj .icon-shape p,#mermaid-svg-K303n3wDcVoolvtj .image-shape p{background-color:rgba(232,232,232, 0.8);padding:2px;}#mermaid-svg-K303n3wDcVoolvtj .icon-shape .label rect,#mermaid-svg-K303n3wDcVoolvtj .image-shape .label rect{opacity:0.5;background-color:rgba(232,232,232, 0.8);fill:rgba(232,232,232, 0.8);}#mermaid-svg-K303n3wDcVoolvtj .label-icon{display:inline-block;height:1em;overflow:visible;vertical-align:-0.125em;}#mermaid-svg-K303n3wDcVoolvtj .node .label-icon path{fill:currentColor;stroke:revert;stroke-width:revert;}#mermaid-svg-K303n3wDcVoolvtj :root{--mermaid-font-family:"trebuchet ms",verdana,arial,sans-serif;} 是
否
否
是
确认业务实际运行时和信任来源
可安装供应商修复更新?
更新对应JDK或系统证书包
按厂商指引处理风险根CA或配置吊销检查
备份并评估合法证书链失效和网络依赖
核对外部truststore和容器挂载
重启或重新部署受影响进程
风险链拒绝且正常链成功?
记录构建号和验证证据
使用应急措施的环境继续跟进正式更新
容器重点: 外部挂载的旧 truststore 可能仍保留风险根 CA,使内置 cacerts 的移除未作用于应用实际信任库。它不会自动撤销新版运行时的所有其他安全机制,是否仍可利用必须结合实际验证路径判断。
7.3 无法立即更新时
| 措施 | 使用条件与边界 |
|---|---|
| 按供应商指导移除相关根 CA | 备份实际信任库,按指纹核对并检查交叉签名路径;删除会影响其他合法证书链,需回归测试和重启 |
| 启用吊销检查 | 按应用和 Provider 配置,验证 CRL/OCSP 可达及失败策略;不能只添加一个参数便宣布安全 |
| 使用限定范围的内部 CA 信任库或固定公钥 | 需保留完整身份验证并设计轮换、过期与故障恢复;自签证书本身不自动带来安全 |
| 监测证书验证失败和异常对端 | 用于发现异常,不能代替撤销信任;也不能保证被动 IDS 能看到全部 TLS 证书信息 |
Oracle 当前应急指导列出四个根证书别名:emsignrootcag1 [jdk]、emsignrootcag2 [jdk]、emsigneccrootcag3 [jdk]、comodoaaaca [jdk]。这是一套针对 Oracle 的操作指导,不能直接套用于所有发行版或自定义 truststore。执行前应阅读原文并匹配实际证书。Oracle 应急指导
对使用相关默认实现的 TLS 应用,Oracle 的应急指导列出以下两个启动属性:
text
-Dcom.sun.net.ssl.checkRevocation=true
-Dcom.sun.security.enableCRLDP=true
它们不是"自动启用并保证所有 OCSP/CRL 场景有效"的通用开关。自定义信任管理器、网络不可达、代理和失败策略均需验证。对于签名 JAR,Oracle 另有 jarsigner 验证建议,不能用 TLS 校验结果代替。Oracle 吊销检查建议
对需要验证的签名 JAR,Oracle 应急指导建议在 JDK 17 及以后使用 jarsigner 的严格验证与吊销检查。按工具文档的参数拼写,示例如下:
bash
/opt/verified-jdk/bin/jarsigner -verify -revCheck -strict /path/to/signed-artifact.jar
需查看退出状态、签名覆盖范围及证书链警告,不能只截取一行"已验证"。该命令不更新业务应用的信任库,也不能覆盖所有供应链与签名者授权问题。jarsigner 官方文档
禁止用关闭主机名校验、信任所有证书或导入未知证书来恢复业务。若合法服务的链因撤销信任而失效,应推动更换证书链,而非重新放回风险信任路径。
7.4 不能作为完成修复的操作
仅复制阻断文件不能作为当前整改完成的依据。 blocked.certs / blacklisted.certs 属于具体运行时实现中的阻断机制;既然首次阻断已被指出不足,就不能将手动替换某个文件视为覆盖后续修复的通用方案。必须遵循当前供应商公告并进行实际验证。
如果 Nginx 只负责入口 HTTPS,Java 仍自行发起下游 TLS,那么 Java 的信任风险仍需处理。若架构确实把出站 TLS 验证交给经过修复的代理,则应沿真实连接路径评估;不能笼统声称任何代理架构都无效。
7.5 修复失败后,先定位链路,不恢复风险信任
| 现象 | 优先核查 |
|---|---|
| 更新后仍接受风险链 | 旧进程、外部 truststore、另一 TLS Provider、交叉签名路径、代理代验 |
| 正常下游连接失败 | 下游仍使用受撤信任的链、遗漏必需中间证书、配置到了错误信任库 |
| 开启吊销检查后超时 | 目标环境对 CRL/OCSP 的 DNS、代理和出站网络访问,以及失败策略 |
| 新实例正常、旧实例异常 | 发布是否覆盖全部副本,连接池、旧会话和安全上下文是否更新 |
这是一份排查方向表,不是对上述现象的唯一归因。应保留失败链和异常证据,与下游证书责任人协作更换链;不要直接回滚到已知存在风险的信任库。
八、常见误区对照表
| 常见说法 | 更准确的结论 |
|---|---|
| "9.1 分,任何人都能直接打 TLS 端口" | 典型攻击需截获或重定向连接,并依赖目标接受风险信任路径 |
| "8u511 / 8u512 以上就统一安全" | 不同发行版和构建策略不同,必须核对完整构建号与公告 |
| "打过 CVE-2026-91403 补丁就完成整改" | 需覆盖后续 CVE-2026-114820 修复 |
| "在 cacerts 删除八张中间证书" | 中间证书可能由对端提供;应按厂商指导处理根信任与交叉签名路径 |
| "四个别名只在 Oracle 上才有效" | 这些命令针对 Oracle 的证书库布局;其他环境需匹配实际证书,不能机械照搬 |
| "内网 HTTPS 一定受影响" | 若只信任独立私有 CA,且没有风险公共 CA 路径,该攻击路径可能不适用 |
| "外部旧 truststore 一定绕过全部补丁" | 它可能使根移除措施未作用于实际信任库;其他防护是否有效需另行验证 |
| "A:N 代表业务绝不可能中断" | A:N 是评分中的可用性影响取值,不承诺没有间接业务后果 |
| "有 Nginx 就够了" | 入口 TLS 终止覆盖不到独立出站连接;出站代理方案需评估实际校验和完整链路 |
| "脚本输出新版本就能验收" | 还要确认进程、信任配置、风险链拒绝与正常链成功 |
九、企业安全治理:补上运行时与证书资产
普通面向 Maven 依赖的 SCA 扫描,不能被默认视为覆盖了 JDK 运行时、系统 CA 包与实际 truststore。部分资产、容器和主机扫描工具可以识别相关软件包漏洞,但仍不应假定它们能还原应用实际采用的信任路径。
建议为每项 Java 服务记录:发行商与完整构建号、进程使用路径、基础镜像摘要、系统证书包、信任库来源、责任人和最近验证日期。将常规更新、紧急补丁和证书轮换纳入维护窗口。
升级验收保留四类证据:供应商修复公告、部署产物标识、实际进程配置、证书验证及业务回归结果。这样才能解释"更新了什么、哪个进程在使用、风险路径是否被阻断"。
发布前可复用的检查清单
- 每个实际使用的运行时、系统 CA 包与外部信任库都有责任人。
- 修复公告、发行商、完整构建号和制品摘要已归档。
- 覆盖全部服务副本、CI 节点及会被重新部署的镜像。
- 新连接拒绝适用风险链,正常业务链路回归通过。
- 适用的代码签名、mTLS、代理链路已分别核查。
- 临时措施有后续更新计划,未以关闭验证恢复业务。
十、官方与一手参考资料及适用范围
本文是公开资料分析,不是对具体生产环境的检测结论。修复版本和证书策略可能继续更新,发布及变更前请复核对应厂商最新公告。本文不提供实际攻击已发生的判断。采集脚本不实施漏洞利用,也不修改证书配置。