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

Kotlin Multiplatform Compose+Ktor自签名证书配置求助

解决KMM中Ktor对接自签HTTPS证书的问题

核心思路

不要用"信任所有证书"的方案(不安全且iOS ATS可能拦截),正确做法是让App仅信任你的自签证书,分Android(OkHttp引擎)和iOS(Darwin引擎)分别配置。


Android端配置(OkHttp引擎)

  • 放置证书
    将你的自签证书(.crt/.pem格式)放到androidMain/res/raw目录(没有raw文件夹就右键res目录新建)。

  • 编写证书加载工具函数
    在androidMain/kotlin下创建工具类:

    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 createSslContext(certInputStream: InputStream): SSLContext {
        val certFactory = CertificateFactory.getInstance("X.509")
        val certificate = certFactory.generateCertificate(certInputStream)
    
        val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()).apply {
            load(null, null)
            setCertificateEntry("custom_cert", certificate)
        }
    
        val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()).apply {
            init(keyStore)
        }
    
        return SSLContext.getInstance("TLS").apply {
            init(null, trustManagerFactory.trustManagers, null)
        }
    }
    
  • 配置Ktor HttpClient
    在Android端的HttpClient配置中,替换OkHttp的SSL配置:

    val httpClient = HttpClient(OkHttp) {
        install(HttpTimeout) {
            requestTimeoutMillis = 15000
        }
        engine {
            config {
                val sslContext = createSslContext(context.resources.openRawResource(R.raw.your_cert_name))
                sslSocketFactory(sslContext.socketFactory, sslContext.trustManagers[0] as X509TrustManager)
            }
        }
    }
    

    注意替换your_cert_name为你证书的文件名(不带后缀)。


iOS端配置(Darwin引擎)

  • 导入证书到项目

    1. 将证书文件放到iosMain/resources目录
    2. 打开Xcode,把证书拖到项目导航栏中,勾选"Copy items if needed",确保它出现在Build Phases > Copy Bundle Resources列表里。
  • 配置Ktor HttpClient
    在iOS端的HttpClient配置中,设置Darwin引擎信任该证书:

    val httpClient = HttpClient(Darwin) {
        install(HttpTimeout) {
            requestTimeoutMillis = 15000
        }
        engine {
            configureSession {
                val certPath = NSBundle.mainBundle.pathForResource("your_cert_name", "crt") // 替换为你的证书后缀
                certPath?.let { path ->
                    val certData = NSData.dataWithContentsOfFile(path)
                    val cert = SecCertificateCreateWithData(null, certData) ?: return@configureSession
                    setHTTPCookieStorage(nil)
                    val trust = SecTrustCreateWithCertificates(cert, SecPolicyCreateSSL(true, null), null)
                    SecTrustSetAnchorCertificates(trust, arrayOf(cert))
                    SecTrustSetAnchorCertificatesOnly(trust, true)
                }
            }
        }
    }
    

    注意替换your_cert_name和证书后缀(比如crt或pem)。


常见问题排查

  • 若之前"信任所有证书"失败:iOS端ATS默认会拦截这种不安全配置,且iOS 13+对SSL配置限制更严,所以不建议用这种方案。
  • 确保证书文件格式正确:如果是.pem格式,要确保文件内容包含-----BEGIN CERTIFICATE-----和-----END CERTIFICATE-----。
  • 检查Ktor版本:不同版本的引擎配置API可能有差异,确保你的Ktor版本和代码适配。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.26 05:00:27