Android 10及以上Retrofit SSL认证报错解决方案咨询
Android 10+ Retrofit SSL认证报错解决方案
问题原因
Android 10及以上系统默认采用Conscrypt作为SSL实现,OkHttp在配置自定义sslSocketFactory时,必须同时传入对应的TrustManager,否则无法从OpenSSLSocketFactoryImpl中提取信任管理器,进而抛出异常。
修复步骤
- 保存初始化完成的
TrustManager实例 - 调用
sslSocketFactory()方法时,同时传入sslSocketFactory和对应的X509TrustManager
修改后的完整代码
public class Api_Client { public static final String BASE_URL = ""; // 替换为你的实际Base URL public static Retrofit retrofit; public static Retrofit getApiClient(Context context) { InputStream is = null; SSLContext sslContext = null; X509TrustManager trustManager = null; // 新增TrustManager变量 if (retrofit == null) { OkHttpClient.Builder builder = new OkHttpClient.Builder(); if (BuildConfig.DEBUG) { HttpLoggingInterceptor logging = new HttpLoggingInterceptor(); logging.setLevel(HttpLoggingInterceptor.Level.BODY); builder.addInterceptor(logging); } CertificateFactory cf = null; try { is = context.getAssets().open("exapmle.pem"); // 你的PEM证书文件 cf = CertificateFactory.getInstance("X.509"); X509Certificate cert = (X509Certificate) cf.generateCertificate(is); KeyStore ks = KeyStore.getInstance(KeyStore.getDefaultType()); ks.load(null, null); ks.setCertificateEntry("alias", cert); TrustManagerFactory tmf = TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm()); tmf.init(ks); // 提取X509TrustManager TrustManager[] trustManagers = tmf.getTrustManagers(); trustManager = (X509TrustManager) trustManagers[0]; sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, trustManagers, null); } catch (CertificateException e) { e.printStackTrace(); } catch (NoSuchAlgorithmException e) { e.printStackTrace(); } catch (KeyStoreException e) { e.printStackTrace(); } catch (KeyManagementException e) { e.printStackTrace(); } catch (IOException e) { e.printStackTrace(); } builder.readTimeout(30, TimeUnit.SECONDS); builder.connectTimeout(30, TimeUnit.SECONDS); // 同时传入sslSocketFactory和trustManager if (sslContext != null && trustManager != null) { builder.sslSocketFactory(sslContext.getSocketFactory(), trustManager); } Retrofit.Builder builder1 = new Retrofit.Builder() .baseUrl(BASE_URL) .addConverterFactory(GsonConverterFactory.create()); retrofit = builder1.client(builder.build()).build(); } return retrofit; } }
额外说明
- 确保证书文件
exapmle.pem正确放置在assets目录下,文件名与代码中保持一致 - 异常处理可根据项目需求优化,比如添加错误日志上报或抛出自定义异常
- 仅测试环境可考虑使用自定义信任所有证书的
X509TrustManager,生产环境强烈禁止该操作
内容的提问来源于stack exchange,提问作者Praveenayya Allayyanavaramath
相关产品推荐
相关产品推荐

