问题描述
我有一个运行一些HTTP GET的应用程序。 该应用程序在API 21+上运行。 在大多数情况下,它都能正常工作,但很少有HTTP GET失败并显示以下错误:
D/OkHttp: --> GET https://url/url2?parm1=value1
D/OkHttp: --> END GET
D/OkHttp: <-- HTTP FAILED: javax.net.ssl.SSLHandshakeException: java.security.cert.CertPathValidatorException: Trust anchor for certification path not found.
当这种情况开始发生时,它一直在发生,直到我杀死该应用程序为止。 我正在将OKHttp 4.3.1与Retrofit一起使用。我现在要更新到最新版本,以防万一这是OKHttp中的错误,但我没有找到任何报告。
HTTP调用的代码是Retrofit的常规代码:
private val retrofit: Retrofit
get() = Retrofit.Builder()
.baseUrl(BuildConfig.BASE_URL)
.addConverterFactory(GsonConverterFactory.create(gson))
.addCallAdapterFactory(CoroutineCallAdapterFactory())
.client(client)
.build()
internal val service: AppService
get() = retrofit.create<AppService>(AppService::class.java)
internal interface AppService {
@GET
suspend fun loadServerListAsync(@Url url: String): Response<List<Server>>
}
过去,我在另一个应用程序中看到过此错误。在那种情况下,错误不是间歇性的,问题出在后端:他们更改了证书,但没有更新所有中间证书。
在这种情况下,错误似乎是不同的,因为它是间歇性的,并且杀死应用程序可以修复该错误。后端没有负载平衡器,因此不可能是不同的服务器具有不同的证书。
编辑
对我来说,这似乎不是重复的,因为所有其他问题都与可重复的问题有关,而不是像这样的间歇性问题
解决方法
它可能与密码安全协议TLSv1发生故障并回退到已弃用的SSLv3有关。
为了防止TLSv1安全连接回退到模拟器中的SSLv3并引发连接错误,因为SSLv3现在已被弃用且不安全(SSL库中的Android Studio失败,通常是协议错误)
使用Google Play服务安装更新的安全提供程序。 这有效地使您的应用程序可以访问较新版本的OpenSSL和Java安全提供程序,其中包括对SSLEngine中的TLSv1.2的支持。 安装新的提供程序后,您可以创建一个SSLEngine,该SSLEngine通常支持SSLv3,TLSv1,TLSv1.1和TLSv1.2。