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引擎)
导入证书到项目
- 将证书文件放到
iosMain/resources目录 - 打开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
相关产品推荐
相关产品推荐

