android - 如何信任具有交叉签名根的 SSL 证书,在 Android <= 5 上已过期

标签 android ssl-certificate retrofit android-5.0-lollipop okhttp

我在一家使用 Comodo/Sectigo SSL 证书的公司工作。但突然间,我们的应用程序在使用 Okhttp 客户端将 POST 发送到服务器时开始抛出此错误(在 Android 4 和 5 版本中)。

HTTP FAILED: javax.net.ssl.SSLHandshakeException: com.android.org.bouncycastle.jce.exception.ExtCertPathValidatorException: Could not validate certificate: Certificate expired at Sat May 30 05:48:38 CDT 2020 (compared to Mon Jun 08 23:13:02 CDT 2020)

我尝试了很多 StackOverflow 解决方案,但没有成功。然后我在Comodo博客上发现了这个交叉签名证书warning

Sectigo at present offers the ability to cross-sign certificates with the AddTrust legacy root to increase support among very old systems and devices. This root is due to expire at the end of May, 2020. Any applications or installations that depend on this cross-signed root must be updated by May, 2020 or run the risk of outage or displayed error message.

我尝试了更多的方法来让我的 okhttp 客户端信任证书(在套接字上启用 TLS,添加现代 TLS、TLS 版本和密码套件以连接 okhttp 构建器中的规范,将证书添加到原始资源中,我也将自定义 SslSocketFactory 放入客户端)但这些都不起作用,总是抛出与证书有效性或握手异常相关的错误。

唯一对我有用的是制作一个不安全的 okhttp,但显然不建议在生产中使用它。

该应用程序在 android > 5 中运行良好,但我们仍然有一些使用 android 5 甚至 4 的用户由于此问题而无法使用该应用程序。还有什么方法可以实现 android <= 5 信任这个过期的 root 吗?

感谢您的帮助

最佳答案

如果证书有效,这应该可以解决问题。

在您的构建文件中

  implementation 'org.conscrypt:conscrypt-android:2.5.1'

并在您提出请求之前激活 Conscrypt

import org.conscrypt.Conscrypt


Security.insertProviderAt(Conscrypt.newProvider(), 1)
val client = OkHttpClient.Builder().build()

val request = Request.Builder().url("https://status.datadoghq.com/").build()
client.newCall(request).execute().use { response ->
  println(response.code())
}

如果此后仍然失败,那么您可能还需要注册自定义证书,但首先在没有此证书的情况下进行测试。

https://github.com/square/okhttp/blob/okhttp_3.12.x/samples/guide/src/main/java/okhttp3/recipes/CustomTrust.java

关于android - 如何信任具有交叉签名根的 SSL 证书,在 Android <= 5 上已过期,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62275157/

相关文章:

android - onStop() 是否总是在 onPause() 之前

android - 无需登录即可访问 Facebook Graph API

ssl - 如何获取 .cer 或 .crt 格式的公钥

android - RxJava 线性退避,在重试时传递较早的日期参数

java - 使用 Retrofit/GSON 如何处理有时为空而有时为空的响应

android - 导航架构组件 - 将参数数据传递给 startDestination

ANDROID -- 如何在图片上显示文字?

ssl - .cert 与 .cacert 之间的区别 (X.509)

java - 证书链验证

java - 如何使用改造获取其中的数据