使用Coil3的Kotlin项目遭遇SSL握手中止错误求助
解决Coil3加载图片时的SSL握手中止错误(TLSV1_ALERT_PROTOCOL_VERSION)
核心问题分析
错误TLSV1_ALERT_PROTOCOL_VERSION本质是客户端与服务器的TLS协议版本协商失败——哪怕你确认服务器支持目标版本,OkHttp的默认ConnectionSpec也可能没覆盖到所有必要的TLS版本,或者存在隐性配置限制。
解决方案步骤
1. 自定义ConnectionSpec,明确指定支持的TLS版本
替换默认的MODERN_TLS和RESTRICTED_TLS,手动锁定服务器支持的TLS版本(比如TLS 1.2、1.3),同时放宽密码套件限制:
val customConnectionSpec = ConnectionSpec.Builder(ConnectionSpec.MODERN_TLS) .tlsVersions(TlsVersion.TLS_1_2, TlsVersion.TLS_1_3) .cipherSuites( CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_AES_128_GCM_SHA256, CipherSuite.TLS_ECDHE_ECDSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_ECDHE_RSA_WITH_AES_256_GCM_SHA384, CipherSuite.TLS_ECDHE_ECDSA_WITH_CHACHA20_POLY1305_SHA256, CipherSuite.TLS_ECDHE_RSA_WITH_CHACHA20_POLY1305_SHA256 ) .build() val client = OkHttpClient().newBuilder() .connectionSpecs(listOf(customConnectionSpec)) // 仅测试时加ConnectionSpec.CLEARTEXT,正式环境务必移除 .build()
2. 强制使用兼容的SSLSocketFactory(全版本兼容方案)
如果自定义ConnectionSpec无效,直接构建支持TLS 1.2+的SSLSocketFactory,绕过系统默认限制:
fun createCompatibleSSLSocketFactory(): SSLSocketFactory { val sslContext = SSLContext.getInstance("TLSv1.2") sslContext.init(null, null, null) return sslContext.socketFactory } val client = OkHttpClient().newBuilder() .sslSocketFactory(createCompatibleSSLSocketFactory(), X509TrustManagerImpl()) .connectionSpecs(listOf(ConnectionSpec.MODERN_TLS)) .build() // 自定义TrustManager(仅用于测试,正式环境必须实现合法的证书校验逻辑) class X509TrustManagerImpl : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun getAcceptedIssuers(): Array<X509Certificate> = emptyArray() }
3. 检查Coil3的OkHttp集成依赖
确保Coil3的OkHttp扩展依赖已正确引入,避免版本冲突:
// build.gradle.kts 中的依赖配置 implementation("io.coil-kt:coil-okhttp:3.0.0")
4. 再次验证服务器的TLS配置
用openssl s_client -connect info.defcon.org:443命令查看服务器实际支持的TLS版本和密码套件,确保客户端配置和服务器完全匹配。
测试建议
- 分别在新旧Android设备上测试,重点关注Android 7.0以下设备(系统默认不支持TLS 1.2)的表现
- 临时启用
ConnectionSpec.CLEARTEXT测试非HTTPS请求,排除SSL证书本身的问题
内容的提问来源于stack exchange,提问作者advice
相关产品推荐
相关产品推荐

