You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Android新旧证书信任差异:旧证正常新证报Trust anchor缺失

Android Retrofit证书信任异常问题

场景与代码

我有一个用Retrofit开发的Android应用,用来调用服务器API。服务器最近更新了证书,应用没有自定义网络配置、证书固定或其他证书自定义规则,初始化代码如下:

object ServiceBuilder {
    fun <T> buildService(service: Class<T>, interceptor: Interceptor): T {

        val moshi = Moshi.Builder()
            .add(KotlinJsonAdapterFactory())
            .build()

        val client: OkHttpClient = OkHttpClient.Builder()
            .followRedirects(false)
            .addInterceptor(interceptor)
            .build()

        val retrofit: Retrofit = Retrofit.Builder()
            .addConverterFactory(MoshiConverterFactory.create(moshi))
            .baseUrl(DemoServerUrl.LOCALHOST_URL.url)
            .client(client)
            .build()

        return retrofit.create(service)
    }
}

旧证书场景

服务器未发送完整证书链,仅发送首证书,但应用能正常调用API。该证书的根证书是Android系统信任的DigiCert Global Root CA;只有禁用这个根证书时才会报错。

新证书场景

服务器同样只发送首证书,应用调用API时出现Trust anchor for certification path not found错误。该证书的根证书是Android系统信任的DigiCert Global Root G2。

已清理测试设备上的所有自定义证书,确保设备没有未知中间证书。

疑问

为什么旧证书能正常调用,新证书不行?按理解Android不会遵循AIA获取缺失链,两者都应该报错才对。


解答

核心原因是旧证书的首证书(服务器证书)要么直接由DigiCert Global Root CA签发,要么其缺失的中间证书已被Android系统预装信任,而新证书对应的中间证书不在系统预装列表里,Android又不会主动通过AIA下载缺失链,导致无法完成信任链验证。

具体拆解:

  • 旧证书场景:虽然服务器只发送了首证书,但如果该证书是根CA直接签发的,系统能直接完成验证;或者对应的中间证书是Android系统默认预装信任的(比如DigiCert的部分中间证书被内置在系统信任库),即便服务器没发,系统也能自动补上缺失的链,完成信任校验。
  • 新证书场景:新的服务器证书由DigiCert Global Root G2下的某个中间CA签发,而这个中间证书不在Android系统的预装信任列表中,服务器又未发送完整证书链,系统找不到能连接到根CA的完整信任路径,就会抛出信任锚找不到的错误。

可以通过以下方式验证结论:

  1. 用openssl s_client -connect 你的域名:443命令查看新旧证书的链结构,对比旧证书的中间证书是否存在于系统信任库中。
  2. 手动将新证书对应的中间证书安装到测试设备,再调用API,如果能正常运行,就说明问题确实出在缺失的中间证书未被系统信任。

内容的提问来源于stack exchange,提问作者Santacrab

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.12 22:06:06