证书不被信任 的警告

更新时间:2026-02-10 来源:TopSSL AI 助理 作者:TopSSL AI 助理

证书不被信任的定义与触发条件

当客户端(如 Android WebView、OkHttp 或系统级 TLS 栈)在建立 HTTPS 连接时,无法将服务器提供的 X.509 证书链验证至一个受信任的根证书,即触发“证书不被信任”警告。该判定发生在 TLS 握手的 Certificate Verify 阶段之后、Finished 消息交换之前,属于协议层强制检查,不可绕过(除非显式禁用证书验证,属严重安全违规)。

Android 系统自 Android 7.0(Nougat)起默认仅信任用户安装的 CA 证书用于用户应用,而系统预置 CA 证书库(/system/etc/security/cacerts/)仅对系统应用和 WebView 组件开放。这意味着:若服务器证书由非系统根证书签发(例如私有 CA、自签名、或新近加入但尚未同步至目标设备的公共 CA),且未通过 NetworkSecurityConfig 显式配置信任锚点,则 Android 应用将拒绝连接并抛出 SSLHandshakeException,WebView 则显示 NET::ERR_CERT_AUTHORITY_INVALID 类似提示。

主题锚点句
本文聚焦于 Android 平台下因证书信任链断裂引发的工程性阻断,不讨论浏览器界面提示样式、用户手动点击“继续访问”的交互路径,亦不覆盖证书吊销状态(OCSP/CRL)未校验导致的误报场景。

证书信任生命周期中的关键断点

证书信任并非静态属性,其有效性依赖于三个动态耦合环节:根证书预置状态、中间证书完整性、以及证书有效期与密钥用途约束。Android 设备的根证书库更新滞后于公共 CA 变更节奏——例如 Let’s Encrypt 的 ISRG Root X1 在 2021 年成为主流信任锚,但部分 Android 6.0 设备因未接收 OTA 更新,仍仅信任 DST Root CA X3,导致其签发的证书在握手时因链终止于未知根而失败。

中间证书缺失是另一高频断点。服务器若未在 TLS ServerHello 中完整发送证书链(仅发送叶证书),而客户端又未缓存对应中间证书(Android 不主动下载缺失中间证书),则信任链构建失败。该问题在 Android 9 及以下版本尤为突出,因其 TLS 栈未实现 RFC 8446 中定义的“post-handshake auth”扩展所支持的动态证书获取机制。

验证方式:从日志到抓包的分层定位

诊断应始于客户端日志:Android 应用可通过 TrustManagerFactory 注入调试型 X509TrustManager,捕获 checkServerTrusted 抛出的异常类型(如 CertPathValidatorException: Trust anchor for certification path not found),直接定位缺失的信任锚。此方法优于仅依赖 OkHttp 的 EventListener,因后者仅暴露连接层级错误,无法区分是 DNS、TCP、TLS 还是证书验证失败。

网络层验证需结合抓包分析。使用 adb shell 启动 openssl s_client -connect example.com:443 -showcerts 可直连服务器并输出完整证书链;对比该输出与 Android 设备上 adb shell run-as com.example.app cat /data/data/com.example.app/files/cert_chain.pem(若应用持久化了证书)是否一致,可确认是否为服务端链发送不全所致。值得注意的是,Android 12 引入了 CertificateTransparencyPolicy,若服务器未提供 SCT(Signed Certificate Timestamp)且策略设为 enforce,亦会触发类似“不被信任”的拒绝行为,但本质属合规性校验而非信任链问题。

信任机制的工程边界与缓解策略

Android 平台的信任机制以“最小特权+显式声明”为设计原则。系统不提供全局证书导入 API(如 iOS 的 SecTrustSettingsSetTrustSettings),所有非系统根证书必须通过 NetworkSecurityConfig 文件声明作用域(<domain-config><debug-overrides>),否则即使用户在设置中安装了 CA 证书,应用仍视其为不可信——这是为防止恶意应用滥用用户安装的调试证书进行中间人攻击。

缓解策略须分场景:面向生产环境,应确保证书由 Android 系统当前信任的公共 CA 签发(参考 AOSP 的 android-root-ca-list 项目),并启用 OCSP Stapling 以减少吊销校验延迟;面向内网或测试环境,必须在 AndroidManifest.xml 中引用 res/xml/network_security_config.xml,并在其中为特定域名配置 <trust-anchors>,明确指定允许的用户证书或自签名根。任何试图通过反射调用 setHostnameVerifier 或重写 TrustManager 实现无验证逻辑的行为,均违反 Google Play 政策且在 Android 10+ 上因 Network Security Config 强制启用而失效。

总结问题

Q:为什么同一张证书在 Chrome 浏览器中正常,但在 Android App 中提示“证书不被信任”?
A:Chrome for Android 使用 Chromium 自维护的根证书库(独立于系统 CA 存储),且默认启用证书透明度和 OCSP Stapling 回退机制;而原生 Android 应用强制依赖系统 CA 库与严格链验证,二者信任锚来源、中间证书补全能力及吊销检查策略均不同。

Q:能否通过代码动态添加根证书而不修改 network_security_config.xml?
A:不能。Android 7.0+ 应用默认忽略用户安装的 CA 证书,且 TrustManager 初始化后不可动态注入新信任锚;唯一合规路径是在编译期通过 NetworkSecurityConfig 声明可信证书集,并将其以 PEM 格式置于 res/raw/ 目录。

立即探索,帮您快速寻找适合您的SSL数字证书 申请SSL证书
免费 SSL 证书申请|HTTPS 加密|企业级 SSL 证书服务 – TopSSL
提供免费与付费SSL证书申请
微信公众号二维码 扫一扫在线咨询
关注 TopSSL 公众号, RSS订阅SSL资讯与技术支持

2004-2026 ©北京传诚信  版权所有 | TopSSL提供免费 SSL 证书与企业级付费证书申请,快速实现 HTTPS 加密  北京市朝阳区鹏景阁大厦16层

技术协助:wo@topssl.cn 企业咨询:vip@topssl.cn