修改主机名后Android出现SSLHandshakeException链验证失败异常求助
Android SSLHandshakeException: Chain validation failed 解决方法
针对切换测试服务器后出现的SSL握手失败问题,结合Postman可正常请求的情况,给出以下解决步骤:
1. 检查测试服务器SSL证书链完整性
Android对SSL证书链的完整性要求严格,Postman会自动补充缺失的中间证书,但Android系统不会。可以通过以下命令验证服务器的证书链:
openssl s_client -connect test.pethouse.ua:443 -showcerts
如果输出中缺少中间证书(仅显示服务器证书和根证书),需要服务器端配置完整的证书链:将服务器证书与对应的中间证书合并为一个文件后重新部署。
2. 处理非公开CA颁发的测试证书
测试环境常使用自签名证书或私有CA颁发的证书,这类证书默认不被Android信任:
- 手动导入证书到模拟器:
- 用浏览器访问
https://test.pethouse.ua,下载证书文件(格式选择.crt) - 在Android模拟器中进入「设置」→「安全」→「加密与凭据」→「从存储安装」,选择下载的证书,设置用途为「VPN和应用」
- 用浏览器访问
- Debug环境临时禁用SSL验证(仅用于调试,禁止生产环境使用):
给OkHttp配置自定义SSLSocketFactory,跳过证书验证:
在Debug构建分支中,判断环境后使用该客户端发起请求。// 仅Debug环境使用,生产环境必须删除此代码 public static OkHttpClient getUnsafeOkHttpClient() { try { 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.getInstance("SSL"); sslContext.init(null, trustAllCerts, new SecureRandom()); SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory(); OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.sslSocketFactory(sslSocketFactory, (X509TrustManager) trustAllCerts[0]); builder.hostnameVerifier((hostname, session) -> true); return builder.build(); } catch (Exception e) { throw new RuntimeException(e); } }
3. 验证Android版本与服务器TLS协议兼容性
部分旧Android版本(如Android 7.0以下)不支持TLS 1.3或现代签名算法,可通过本地工具测试服务器的TLS协议支持情况。若存在兼容性问题:
- 服务器端调整配置,启用兼容的TLS版本(如TLS 1.2)
- 在Android代码中强制指定支持的协议:
OkHttpClient.Builder builder = new OkHttpClient.Builder(); builder.connectionSpecs(Arrays.asList(ConnectionSpec.MODERN_TLS, ConnectionSpec.COMPATIBLE_TLS));
内容的提问来源于stack exchange,提问作者Олександр Катреніч
相关产品推荐
相关产品推荐

