HTTPS连接时出现PKIX path building failed的解决方法

本文介绍HTTPS连接中PKIX path building failed错误的原因及其两种解决方案,重点推荐并详细展示了通过实现X509TrustManager接口来建立无信任证书的HTTPS连接的方法。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

一、HTTPS连接时出现PKIX path building failed问题

原因:网站进行HTTPS连接时网站根证书出错而报的错

解决方法:

第一种方法:进行安全证书的下载及导入-----------传统办法,优点是安全性高,缺点是网站若更换证书,还得重新下载和导入,不够灵活

第二种方法:进行无信任证书连接,自己实现对网站证书的免验证通过-----------另辟蹊径,优点是灵活,不用担心网站证书的更换或过期等导致系统问题,缺点是有一点风险(其实可以忽略),推荐采用第二种方法,具体实现案例如下。

二、无信任证书连接的实现

在微博实名认证时需要与第三方平台进行https通信,对方因更换网站安全证书,导致通行证系统连接失败,经研究发现原有方法(采用org.codehaus.xfire.transport.http.EasySSLProtocolSocketFactory)不适用新的安全证书验证规范,因此将其进行改进,变为对无证书网站进行https连接时进行无条件信任通过,以避免日后再出现因安全证书更换而导致的系统问题。

原有连接方式:(采用org.codehaus.xfire.transport.http.EasySSLProtocolSocketFactory)

对EasySSLProtocolSocketFactory的解释(网上来源),关键词:自注册证书、不应使用在生产环境

ProtocolSocketFactory easy = new EasySSLProtocolSocketFactory();

Protocol protocol = new Protocol("https", easy, 443);

Protocol.registerProtocol("https", protocol);

//构造HttpClient的实例 
HttpClient httpClient = new HttpClient();

httpClient.getHostConfiguration().setHost("auth.cnidrz.cn", 443, protocol);

httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");

//创建GET方法的实例 
GetMethod getMethod = new GetMethod(url);

try{ 
   //执行getMethod 
   BindPersonalId_DirectAction.trustAllHttpsCertificates();//先执行一遍这个使得网站被信任
   int statusCode = httpClient.executeMethod(getMethod); 
   if (statusCode != HttpStatus.SC_OK) { 
   System.err.println("Method failed: " 
   + getMethod.getStatusLine()); 
   }
   //读取内容 
   temp_id = getMethod.getResponseBodyAsString();
   }catch(Exception e){
     e.printStackTrace();
     throw new Exception("认证失败,原因:[认证系统异常].");
   }finally{ 
   //释放连接 
     getMethod.releaseConnection(); 
   }

现有连接方式:(采用实现X509TrustManager接口方法)

HttpClient httpClient = new DefaultHttpClient(); //创建默认的httpClient实例 
X509TrustManager xtm = new X509TrustManager(){ //创建TrustManager 
public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {} 
public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {} 
public X509Certificate[] getAcceptedIssuers() { return null; } 
}; 
try { 
//TLS1.0与SSL3.0基本上没有太大的差别,可粗略理解为TLS是SSL的继承者,但它们使用的是相同的SSLContext 
SSLContext ctx = SSLContext.getInstance("SSL");  -----------------注意:经测试发现,这里必须是"SSL"实例而非“TLS”,具体原因还不清楚

//使用TrustManager来初始化该上下文,TrustManager只是被SSL的Socket所使用 
ctx.init(null, new TrustManager[]{xtm}, null); 

//创建SSLSocketFactory 
SSLSocketFactory socketFactory = new SSLSocketFactory(ctx); 

//通过SchemeRegistry将SSLSocketFactory注册到我们的HttpClient上 
httpClient.getConnectionManager().getSchemeRegistry().register(new Scheme("https", socketFactory, 443)); 
httpClient.getParams().setParameter(HttpMethodParams.HTTP_CONTENT_CHARSET, "UTF-8");

//创建HttpGet方法的实例 
HttpGet httpGet = new HttpGet(url); //创建HttpPost 
HttpResponse response = httpClient.execute(httpGet); 

//执行 
if(response.getStatusLine().getStatusCode() == 200) 

  //读取内容 
  HttpEntity entity = response.getEntity(); //获取响应实体 
  if (null != entity) { 
  temp_id = EntityUtils.toString(entity, "UTF-8"); 

}else{
  System.out.println("获取temp_id时,认证平台发生内部错误!!");
}
}catch(Exception e){
  e.printStackTrace();
  throw new Exception("认证失败,原因:[认证系统异常].");
}finally{ 
  //释放连接 
  httpClient.getConnectionManager().shutdown(); //关闭连接,释放资源 
}

### PKIX Path Building Failed 错误解决方案 当 Java 应用程序尝试通过 HTTPS 进行通信,如果遇到 `PKIX path building failed` 错误,则表明客户端无法验证服务器 SSL/TLS 证书的有效性。这通常是因为缺少信任链中的根证书或中间证书。 以下是几种常见的解决方法: #### 方法一:导入目标站点的证书到 JVM 的信任库 可以通过以下步骤将目标站点的证书导入到 Java 的信任库中: 1. 使用工具(如浏览器或 OpenSSL)导出目标站点的 SSL 证书。 2. 将导出的证书文件安装到 Java 的默认信任库 (`cacerts`) 中。命令如下: ```bash keytool -importcert -file exported_cert.crt -keystore $JAVA_HOME/lib/security/cacerts -alias myAlias ``` 默认密码通常是 `changeit`[^3]。 #### 方法二:禁用 SSL 验证(仅用于测试) 对于开发阶段或调试场景,可以选择临忽略 SSL 验证。注意此方法不适合生产环境,因为它会降低安全性。可以在代码中实现自定义的信任管理器来跳过证书验证: ```java import javax.net.ssl.*; import java.security.cert.X509Certificate; public class TrustAllCertificates { public static void disableSSLCertificateCheck() { try { // 创建一个不执行任何检查的信任管理器 TrustManager[] trustAllCerts = new TrustManager[]{ new X509TrustManager() { @Override public X509Certificate[] getAcceptedIssuers() { return null; } @Override public void checkClientTrusted(X509Certificate[] certs, String authType) {} @Override public void checkServerTrusted(X509Certificate[] certs, String authType) {} } }; // 安装新的信任管理器 SSLContext sc = SSLContext.getInstance("TLS"); sc.init(null, trustAllCerts, new java.security.SecureRandom()); HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory()); // 创建允许所有主机名的 HostnameVerifier HostnameVerifier allHostsValid = (hostname, session) -> true; HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid); } catch (Exception e) { e.printStackTrace(); } } } ``` #### 方法三:升级 JDK 或 Gradle 版本 某些情况下,旧版 JDK 可能缺乏最新的根证书支持,从而引发此类问题。例如,在 Android Studio 中构建项目可能会因为使用的 JDK 版本较老而导致此错误。此可以考虑升级 JDK 和 Gradle 到最新版本[^4]。 #### 方法四:手动指定 Maven/Gradle 的 CA 文件路径 如果是在构建工具(Maven 或 Gradle)运行过程中遇到了该问题,也可以通过设置 `-Djavax.net.ssl.trustStore` 参数指向特定的信任存储位置来进行修复。例如: ```bash -Djavax.net.ssl.trustStore=/path/to/custom/truststore.jks \ -Djavax.net.ssl.trustStorePassword=yourpassword ``` --- ### 总结 针对不同应用场景可采取不同的策略应对 `PKIX path building failed` 错误。推荐优先采用第一种方式即正确配置受信证书;而在特殊需求下才考虑其他替代手段比如关闭SSL校验但需谨慎对待以免引入安全隐患。
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值