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

Android端程序化重建证书链解决服务器证书不完整问题

程序化修复Android端*.nkust.edu.tw证书链不完整问题

问题背景

我的Android应用需要登录并爬取*.nkust.edu.tw域名下的数据,但该服务器证书链安装不完整,导致使用Kotlin+Ktor发起网络请求时,下载PDF等操作会抛出sun.security.provider.certpath.SunCertPathBuilderException异常。由于无法修改服务器配置,需通过程序化方式重建证书链来解决问题。此前参考过将单个证书添加到信任管理器的方案,但不适用于证书链不完整的场景。

解决方案步骤

1. 生成完整证书链文件

获取该域名对应的服务器证书、中间UCA证书、根证书,将三个证书按「服务器证书 → 中间UCA证书 → 根证书」的顺序合并为一个PEM格式的证书文件(后缀为.pem),并将文件放置在Android项目的res/raw目录下。

2. 在Ktor中配置自定义SSL信任管理器

通过自定义TrustManager加载完整证书链,替换Ktor默认的SSL验证逻辑,具体实现代码如下:

import io.ktor.client.HttpClient
import io.ktor.client.engine.android.Android
import java.io.InputStream
import java.security.KeyStore
import java.security.cert.CertificateFactory
import javax.net.ssl.SSLContext
import javax.net.ssl.TrustManagerFactory
import javax.net.ssl.X509TrustManager

fun createCustomHttpClient(context: Context): HttpClient {
    // 读取raw目录下的完整证书链文件
    val certInputStream: InputStream = context.resources.openRawResource(R.raw.full_chain)

    // 初始化证书工厂和密钥库
    val certificateFactory = CertificateFactory.getInstance("X.509")
    val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
        load(null)
        // 将证书链中的所有证书加载到密钥库
        val certificates = certificateFactory.generateCertificates(certInputStream)
        certificates.forEachIndexed { index, cert ->
            setCertificateEntry("cert_$index", cert)
        }
    }

    // 构建自定义TrustManager
    val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
        init(keyStore)
    }
    val trustManagers = trustManagerFactory.trustManagers
    val x509TrustManager = trustManagers.first { it is X509TrustManager } as X509TrustManager

    // 创建SSLContext并设置自定义TrustManager
    val sslContext = SSLContext.getInstance("TLS").apply {
        init(null, arrayOf(x509TrustManager), java.security.SecureRandom())
    }

    // 配置Ktor HttpClient
    return HttpClient(Android) {
        engine {
            sslContext = sslContext
        }
    }
}

注意事项

  • 务必确保获取的证书来源可靠,避免加载恶意证书导致中间人攻击风险。
  • 证书链的顺序不能颠倒,必须以服务器证书开头,依次到中间证书、根证书,否则证书验证依然会失败。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.18 03:35:34