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

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了HTTPS连接时出现PKIX path building failed问题相关的知识,希望对你有一定的参考价值。

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

 

sudo keytool -import -noprompt -trustcacerts -alias CTSite -file /Users/zhanghao/Desktop/sslvpn.cer -keystore /Library/Java/JavaVirtualMachines/jdk1.8.0_40.jdk/Contents/Home/jre/lib 

 

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

  在微博实名认证时需要与第三方平台进行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(); //关闭连接,释放资源 

}

以上是关于HTTPS连接时出现PKIX path building failed问题的主要内容,如果未能解决你的问题,请参考以下文章

异常解决:sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.cer

ValidatorException: PKIX path building failed

https开头的URL接口无法获取数据并报错: PKIX path building failed

Java访问https时解决sun.security.validator.ValidatorException: PKIX path building failed 问题

java程序中访问https时,报 PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderExcept

解决PKIX path building failed