手机和操作系统

Trust anchor not found:安卓 App 不信任用户安装的 CA

作者: · 最后核实

报错信息SSLHandshakeException: Trust anchor for certification path not found (user-installed CA)

在 Android 7.0 及以后,除非 App 明确声明,否则它会忽略用户自己安装的 CA 证书。 所以公司根证书、学校 Wi-Fi 证书或调试代理的根证书装上以后,网站在 Chrome 里正常,App 却一直报证书错误。这是系统有意的安全设计,不是手机坏了。

先判断是网站的问题还是你设备的问题

服务器用有效的公开证书时,App 不需要任何用户 CA,问题出在网络或 App 配置上。先用 SSL 检测 确认服务器用的是哪种证书:

curl ssl.sh/example.com
  • 服务器用的是有效的公开证书:App 不需要任何用户 CA 就该正常。只在某个网络里失败,说明那个网络在拦截 TLS(见 公司 SSL 解密)。
  • 服务器用私有 CA,或者流量必须经过检查代理:要么 App 配置信任这个 CA,要么服务器换成公开证书。

原因

最常见的情况是 App 目标 API 为 24 及以上,又没有声明信任用户 CA;公司 SSL 解密、调试抓包和内部私有 CA 也会触发。

1. App 目标 API 24+,且没有声明信任用户 CA

现代 App 的默认信任配置只包含系统 CA,在设置里装根证书对它们没有任何影响。开发者可以这样确认:

adb logcat | grep -iE "trust anchor|CertPathValidatorException|SSLHandshakeException"

2. 公司网络做了 SSL 解密

公司代理用自己的根证书重新签发 HTTPS。信任用户或管理员 CA 的浏览器能用,App 失败。要在公司这边解决:把 App 流量排除在解密之外,或者用设备管理把 CA 下发给 App。

3. 调试抓包代理的根证书

开发者抓 App 流量时会把代理根证书装成用户 CA。自己的调试版本需要 <debug-overrides>;第三方的正式版 App 不会信任它,这是故意的。

4. 内部接口用私有 CA

公司 CA 签发的内部服务,需要 App 内置这个 CA,或者在网络安全配置里引用它。

在各浏览器/系统上的样子

场景 显示内容
安卓 App(Java/Kotlin) javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
安卓 Chrome 装了用户 CA 后能正常打开
安卓系统 通知栏或设置里提示网络可能受到监控
iOS App 需要安装根证书并打开完全信任(见 iOS 无法验证服务器身份)

站长怎么修

1. 手机访问的接口一律优先用公开证书。 这样就不需要任何用户 CA,用 curl ssl.sh/example.com 确认证书链即可。阿里云、腾讯云的负载均衡和 API 网关都可以直接绑定公开证书。

2. 针对特定域名内置私有 CA,写在 res/xml/network_security_config.xml:

<network-security-config>
  <domain-config>
    <domain includeSubdomains="true">internal.example.com</domain>
    <trust-anchors>
      <certificates src="@raw/company_root"/>
      <certificates src="system"/>
    </trust-anchors>
  </domain-config>
  <debug-overrides>
    <trust-anchors>
      <certificates src="user"/>
    </trust-anchors>
  </debug-overrides>
</network-security-config>

在清单文件里用 android:networkSecurityConfig="@xml/network_security_config" 引用它。

3. 正式版不要信任用户 CA,除非 App 专门面向公司统一管理的设备。

常见问题

能不改 App,让所有 App 都信任公司的 CA 吗?

普通的用户安装证书做不到。受管理的设备可以通过 Android 企业版的设备策略下发 CA,但每个 App 仍然自己决定是否信任用户或管理员添加的 CA。对外提供的服务应该直接用公开信任的证书。

正式版 App 信任用户 CA 安全吗?

不安全。只要能哄用户装一张根证书,就能拦截这个 App 的流量,大多数 App 都不应该这么做。只在调试版本里用 <debug-overrides>,或者只针对确实在公司 CA 后面的特定域名开启。

安卓上在哪里安装和查看用户证书?

一般在“设置 → 安全(或安全和隐私)→ 加密与凭据 → 安装证书 → CA 证书”。国产手机(华为、小米、OPPO、vivo 等)菜单名称各不相同,可以直接在设置里搜索“证书”或“凭据”;已安装的证书在“用户凭据”或“受信任的凭据 → 用户”里。

资料来源

  1. Android Developers:网络安全配置
  2. Android Developers:使用网络协议确保安全
  3. RFC 5280: X.509 certificate profile