解决因终端时间与当前时间差异较大,造成的okhttp请求异常的问题Could not validate.certificate:null

当Android应用遇到SSLHandshakeException,特别是在设备时间错误时,可以使用自定义的TrustManager和HostnameVerifier来绕过证书验证。通过创建TrustAllManager和TrustAllHostnameVerifier,允许所有证书和主机名,从而解决请求问题。但这可能导致安全风险,仅建议用于测试环境。

近期开发安卓程序时,遇到一个问题,当终端的时间是过去的一个时间,在OKhttp请求时报异常,异常信息如下:javax.net.ssl.SSLHandshakeException:com.android.org.bouncycastle.jce.exception.ExtcertPathValidatorException:Could not validate.certificate:null

解决办法如下:

    OkHttpClient okHttpClient =new OkHttpClient.Builder().
//很重要,这句话,增加这句话,下面这两句话
                           hostnameVerifier((hostname, session) -> true).

                            sslSocketFactory(createSSLSocketFactory()).
                           build();

SSL验证方法如下



    @SuppressLint("TrulyRandom")
    public static SSLSocketFactory createSSLSocketFactory() {
        SSLSocketFactory sSLSocketFactory = null;
        try {
            SSLContext sc = SSLContext.getInstance("TLS");
            sc.init(null, new TrustManager[]{new TrustAllManager()},
                    new SecureRandom());
            sSLSocketFactory = sc.getSocketFactory();
        } catch (Exception 
### OkHttp Java 中解决 CertPathValidatorException: Trust anchor for certification path not found 的方法 在 OkHttp 使用过程中,如果遇到 `CertPathValidatorException: Trust anchor for certification path not found` 异常,通常是由于 HTTPS 请求中服务器证书无法被信任导致的。以下是几种解决方案: #### 1. 检查网络环境和服务器证书 首先需要确认设备是否连接到了正确的网络环境[^1]。例如,如果设备连接到一个不安全的 Wi-Fi 网络,可能会导致请求被中间人攻击(MITM),从而引发证书验证失败。确保设备连接的是可信网络。 此外,检查目标服务器的 SSL 证书是否有效。可以通过浏览器访问目标 URL,并查看其证书信息。如果发现证书无效或过期,则需要联系服务器管理员更新证书。 #### 2. 导出并加载自定义证书 如果目标服务器使用的是自签名证书或内部 CA 签发的证书,OkHttp 默认不会信任这些证书。可以手动导入服务器证书并配置 OkHttp 客户端进行信任。 以下是一个示例代码,展示如何加载自定义证书: ```java import java.io.InputStream; import java.security.KeyStore; import java.security.cert.CertificateFactory; import javax.net.ssl.SSLContext; import javax.net.ssl.TrustManagerFactory; import okhttp3.OkHttpClient; public class CustomTrustManager { public static OkHttpClient getUnsafeOkHttpClient() throws Exception { // 加载证书文件 InputStream certificateInputStream = CustomTrustManager.class.getResourceAsStream("/path/to/certificate.cer"); CertificateFactory certificateFactory = CertificateFactory.getInstance("X.509"); java.security.cert.Certificate certificate = certificateFactory.generateCertificate(certificateInputStream); // 创建 KeyStore 并加载证书 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("certificate", certificate); // 初始化 TrustManagerFactory String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory trustManagerFactory = TrustManagerFactory.getInstance(tmfAlgorithm); trustManagerFactory.init(keyStore); // 配置 SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagerFactory.getTrustManagers(), null); // 创建 OkHttpClient 并设置 SSLSocketFactory return new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory(), (javax.net.ssl.X509TrustManager) trustManagerFactory.getTrustManagers()[0]) .build(); } } ``` 上述代码中,通过加载目标服务器的证书文件,创建了一个自定义的信任管理器,并将其应用到 OkHttp 客户端中[^2]。 #### 3. 全局禁用证书验证(不推荐) 虽然可以通过全局禁用 SSL 证书验证来快速解决问题,但这种方法会降低安全性,因此仅适用于测试环境。以下是实现代码: ```java import javax.net.ssl.*; import java.security.cert.X509Certificate; import okhttp3.OkHttpClient; public class UnsafeOkHttpClient { public static OkHttpClient getUnsafeOkHttpClient() throws Exception { // 创建一个空的 TrustManager final TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public void checkClientTrusted(X509Certificate[] chain, String authType) {} @Override public void checkServerTrusted(X509Certificate[] chain, String authType) {} @Override public X509Certificate[] getAcceptedIssuers() { return new X509Certificate[]{}; } } }; // 配置 SSLContext SSLContext sslContext = SSLContext.getInstance("SSL"); sslContext.init(null, trustAllCerts, new java.security.SecureRandom()); // 创建 OkHttpClient 并设置 SSLSocketFactory return new OkHttpClient.Builder() .sslSocketFactory(sslContext.getSocketFactory(), (X509TrustManager) trustAllCerts[0]) .hostnameVerifier((hostname, session) -> true) .build(); } } ``` 这种方法绕过了所有 SSL 证书验证逻辑,因此可能导致中间人攻击风险增加。 #### 4. 更新系统信任库 如果服务器使用的是公共 CA 签发的证书,但仍然出现 `Trust anchor for certification path not found` 错误,可能是由于本地 JVM 或 Android 系统的信任库未包含该 CA。尝试更新 JVM 或 Android 系统的信任库以支持最新的 CA 列表。 --- ### 总结 当 OkHttp 在 Java 中遇到 `CertPathValidatorException: Trust anchor for certification path not found` 时,可能的原因包括网络问题、服务器证书无效或自签名证书。根据具体场景选择合适的解决方案:检查网络环境、加载自定义证书、或全局禁用证书验证(仅限测试环境)。 ---
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值