Android Studio中Kotlin集成Retrofit调用API遇SSL握手异常
解决Retrofit调用API时的
javax.net.ssl.SSLHandshakeException: Chain validation failed问题 一、先排查证书本身的问题
- 先确认目标API的证书状态:用浏览器打开API地址,查看证书详情,检查证书链是否完整(有没有缺失中间证书)。如果是自签名证书,设备默认不会信任。
- 要是正规CA签发的证书仍报错,大概率是服务器没配置完整的证书链,得让后端修复证书链部署。
二、开发环境临时方案(仅测试用,禁止生产环境使用)
如果是开发阶段用自签名/测试环境证书,可以自定义OkHttpClient跳过SSL验证——注意这会降低安全性,只适合开发调试:
fun createUnsafeOkHttpClient(): OkHttpClient { return try { // 创建信任所有证书的TrustManager val trustAllCerts = arrayOf<TrustManager>(object : X509TrustManager { override fun checkClientTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun checkServerTrusted(chain: Array<out X509Certificate>?, authType: String?) {} override fun getAcceptedIssuers(): Array<X509Certificate> = arrayOf() }) // 初始化SSLContext val sslContext = SSLContext.getInstance("SSL") sslContext.init(null, trustAllCerts, SecureRandom()) val sslSocketFactory = sslContext.socketFactory OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustAllCerts[0] as X509TrustManager) .hostnameVerifier { _, _ -> true } // 跳过主机名验证 .build() } catch (e: Exception) { throw RuntimeException(e) } }
创建Retrofit时用上这个客户端:
val retrofit = Retrofit.Builder() .baseUrl("你的API地址") .client(createUnsafeOkHttpClient()) .addConverterFactory(GsonConverterFactory.create()) .build()
三、生产环境正确解决方案
1. 将目标证书导入应用
如果是自签名或私有CA签发的证书,把证书文件放到项目res/raw目录下,然后自定义TrustManager信任该证书:
fun createCustomTrustOkHttpClient(context: Context): OkHttpClient { return try { // 读取raw目录下的证书文件 val certInputStream = context.resources.openRawResource(R.raw.your_certificate) val certFactory = CertificateFactory.getInstance("X.509") val certificate = certFactory.generateCertificate(certInputStream) // 把证书存入KeyStore val keyStore = KeyStore.getInstance(KeyStore.getDefaultType()) keyStore.load(null, null) keyStore.setCertificateEntry("ca", certificate) // 初始化TrustManagerFactory val trustManagerFactory = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()) trustManagerFactory.init(keyStore) val trustManagers = trustManagerFactory.trustManagers // 配置SSLContext val sslContext = SSLContext.getInstance("TLS") sslContext.init(null, trustManagers, SecureRandom()) val sslSocketFactory = sslContext.socketFactory OkHttpClient.Builder() .sslSocketFactory(sslSocketFactory, trustManagers[0] as X509TrustManager) .build() } catch (e: Exception) { throw RuntimeException(e) } }
2. 修复服务器证书链配置
如果是正规CA签发的证书报错,基本是服务器只部署了服务器证书,没加中间证书。让后端把完整证书链(服务器证书+所有中间证书)配置到服务器上,可对照浏览器里的证书链内容来调整。
四、额外排查点
- 检查设备系统时间:如果设备时间和证书有效期不匹配,也会触发链验证失败。
- 确认API地址正确性:要是域名写错,指向了其他证书的服务器,同样会报错。
内容的提问来源于stack exchange,提问作者Tino
相关产品推荐
相关产品推荐

