Android API24出现SSLHandshakeException,API26正常的解决方法
问题原因分析
- Android 7.x(API24-25)系统的根证书库未包含你调用的API所使用的SSL证书的根证书,而Android 8.0(API26)及后续版本的系统根证书库已更新包含该根证书,因此高版本能正常请求,低版本触发信任锚找不到的异常。
- Postman能正常请求是因为它使用独立的根证书存储,已包含该API的根证书,和Android系统的证书库无关联。
解决办法
方法1:打包API根证书到应用,让Volley信任该证书(推荐生产环境)
- 导出API域名的根证书:
- 用浏览器打开API地址,点击地址栏锁图标查看证书详情,导出根证书为
.cer格式(注意选择根证书,不是服务器证书)。
- 用浏览器打开API地址,点击地址栏锁图标查看证书详情,导出根证书为
- 将证书放入
app/src/main/res/raw目录(无raw文件夹则新建)。 - 创建自定义
SSLSocketFactory和TrustManager,让Volley使用该信任配置:private SSLSocketFactory getCustomSSLSocketFactory(Context context) throws CertificateException, IOException, KeyStoreException, NoSuchAlgorithmException, KeyManagementException { // 加载raw目录下的证书 CertificateFactory cf = CertificateFactory.getInstance("X.509"); InputStream certInputStream = context.getResources().openRawResource(R.raw.your_cert_name); Certificate ca; try { ca = cf.generateCertificate(certInputStream); } finally { certInputStream.close(); } // 创建密钥库并添加证书 KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType()); keyStore.load(null, null); keyStore.setCertificateEntry("ca", ca); // 初始化TrustManagerFactory String tmfAlgorithm = TrustManagerFactory.getDefaultAlgorithm(); TrustManagerFactory tmf = TrustManagerFactory.getInstance(tmfAlgorithm); tmf.init(keyStore); // 创建并初始化SSLContext SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, tmf.getTrustManagers(), null); return sslContext.getSocketFactory(); } - 创建Volley的
RequestQueue时,设置自定义HurlStack:RequestQueue queue; try { SSLSocketFactory sslSocketFactory = getCustomSSLSocketFactory(this); HurlStack hurlStack = new HurlStack(null, sslSocketFactory); queue = Volley.newRequestQueue(this, hurlStack); } catch (Exception e) { // 异常处理,降级到默认请求队列 queue = Volley.newRequestQueue(this); e.printStackTrace(); }
方法2:临时绕过SSL验证(仅测试环境使用,禁止生产环境)
如果是测试阶段快速验证功能,可临时跳过SSL证书验证,但会引入安全风险:
private SSLSocketFactory getUnsafeSSLSocketFactory() throws NoSuchAlgorithmException, KeyManagementException { SSLContext sslContext = SSLContext.getInstance("TLS"); sslContext.init(null, 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[0]; } } }, new SecureRandom()); return sslContext.getSocketFactory(); }
创建RequestQueue时将上述SSLSocketFactory传入HurlStack即可。
方法3:检查API服务器的证书链配置
部分服务器仅配置了服务器证书,未配置完整的中间证书链,导致低版本Android无法完成证书链构建。可通过SSL检测工具验证证书链完整性,若不完整,联系服务器运维人员补充中间证书。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

