调用webservice https接口报:PKIX path building failed 解决方案

一套很老的axis2调用webservice的https接口报,如下错误:
分析:这是由于客户端证书校验失败的提示,那么如何避免证书的校验呢,这里我们采用了信任所有证书来避免校验,进而正常调用webservice的https接口。

org.apache.axis2.AxisFault: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at org.apache.axis2.AxisFault.makeFault(AxisFault.java:417)
	at org.apache.axis2.transport.http.SOAPMessageFormatter.writeTo(SOAPMessageFormatter.java:72)
	at org.apache.axis2.transport.http.AxisRequestEntity.writeRequest(AxisRequestEntity.java:84)
	at org.apache.commons.httpclient.methods.EntityEnclosingMethod.writeRequestBody(EntityEnclosingMethod.java:495)
	at org.apache.commons.httpclient.HttpMethodBase.writeRequest(HttpMethodBase.java:1973)
	at org.apache.commons.httpclient.HttpMethodBase.execute(HttpMethodBase.java:993)
	at org.apache.commons.httpclient.HttpMethodDirector.executeWithRetry(HttpMethodDirector.java:397)
	at org.apache.commons.httpclient.HttpMethodDirector.executeMethod(HttpMethodDirector.java:170)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:396)
	at org.apache.commons.httpclient.HttpClient.executeMethod(HttpClient.java:346)
	at org.apache.axis2.transport.http.AbstractHTTPSender.executeMethod(AbstractHTTPSender.java:520)
	at org.apache.axis2.transport.http.HTTPSender.sendViaPost(HTTPSender.java:191)
	at org.apache.axis2.transport.http.HTTPSender.send(HTTPSender.java:77)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.writeMessageWithCommons(CommonsHTTPTransportSender.java:327)
	at org.apache.axis2.transport.http.CommonsHTTPTransportSender.invoke(CommonsHTTPTransportSender.java:206)
	at org.apache.axis2.engine.AxisEngine.send(AxisEngine.java:396)
	at org.apache.axis2.description.OutInAxisOperationClient.send(OutInAxisOperation.java:374)
	at org.apache.axis2.description.OutInAxisOperationClient.executeImpl(OutInAxisOperation.java:211)
	at org.apache.axis2.client.OperationClient.execute(OperationClient.java:163)

解决方案:

public UMessageTransporterDAOImpl(UserToken user, String serviceUrl) throws UMessageTransportException {
		this.user = user;
		try {
			
			stub = new ExchangeTransportServiceStub(serviceUrl); 
			stub2 = new ExchangeTransportServiceStub2(serviceUrl); 
			
			//zjw 2017-12-16
			//********************免证书验证**********************//
			URL url = null;
			try {
				url = new URL(serviceUrl);
				if(url!=null){
					if(url.getProtocol().equalsIgnoreCase("https")){
						MySSLTrustManager.trustAllCertsBySSL(stub);
						MySSLTrustManager.trustAllCertsBySSL(stub2);
					}
				}
			} catch (MalformedURLException e) {
				// TODO Auto-generated catch block
				e.printStackTrace();
			}
			//**************************************************//
		} catch (AxisFault e) {
			throw new UMessageTransportException("Create client error.", e);
		}

	}
import java.io.IOException;  
import java.net.InetAddress;  
import java.net.InetSocketAddress;  
import java.net.Socket;  
import java.net.SocketAddress;  
import java.net.UnknownHostException;  
import java.security.KeyManagementException;  
import java.security.NoSuchAlgorithmException;  
import java.security.cert.CertificateException;  
import java.security.cert.X509Certificate;  
  
import javax.net.SocketFactory;  
import javax.net.ssl.SSLContext;  
import javax.net.ssl.TrustManager;  
import javax.net.ssl.X509TrustManager;  
  
import org.apache.commons.httpclient.ConnectTimeoutException;  
import org.apache.commons.httpclient.params.HttpConnectionParams;  
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;  
  
  
  
/** 
 * @author zjw 
 * @describes 
 * @date 2017-12-16
 */  
public class MySSLProtocolSocketFactory implements ProtocolSocketFactory {  
  
  private SSLContext sslcontext = null;   
   
  private SSLContext createSSLContext() {   
      SSLContext sslcontext=null;   
      try {   
          sslcontext = SSLContext.getInstance("SSL");   
          sslcontext.init(null, new TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());   
      } catch (NoSuchAlgorithmException e) {   
          e.printStackTrace();   
      } catch (KeyManagementException e) {   
          e.printStackTrace();   
      }   
      return sslcontext;   
  }   
   
  private SSLContext getSSLContext() {   
      if (this.sslcontext == null) {   
          this.sslcontext = createSSLContext();   
      }   
      return this.sslcontext;   
  }   
   
  public Socket createSocket(Socket socket, String host, int port, boolean autoClose)   
          throws IOException, UnknownHostException {   
      return getSSLContext().getSocketFactory().createSocket(   
              socket,   
              host,   
              port,   
              autoClose   
          );   
  }   
  
  public Socket createSocket(String host, int port) throws IOException,   
          UnknownHostException {   
      return getSSLContext().getSocketFactory().createSocket(   
              host,   
              port   
          );   
  }   
   
   
  public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)   
          throws IOException, UnknownHostException {   
      return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);   
  }   
  
  public Socket createSocket(String host, int port, InetAddress localAddress,   
          int localPort, HttpConnectionParams params) throws IOException,   
          UnknownHostException, ConnectTimeoutException {   
      if (params == null) {   
          throw new IllegalArgumentException("Parameters may not be null");   
      }   
      int timeout = params.getConnectionTimeout();   
      SocketFactory socketfactory = getSSLContext().getSocketFactory();   
      if (timeout == 0) {   
          return socketfactory.createSocket(host, port, localAddress, localPort);   
      } else {   
          Socket socket = socketfactory.createSocket();   
          SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);   
          SocketAddress remoteaddr = new InetSocketAddress(host, port);   
          socket.bind(localaddr);   
          socket.connect(remoteaddr, timeout);   
          return socket;   
      }   
  }   
   
  //自定义私有类   
  private static class TrustAnyTrustManager implements X509TrustManager {   
      
      public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {   
      }   
  
      public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {   
      }   
  
      public X509Certificate[] getAcceptedIssuers() {   
          return new X509Certificate[]{};   
      }   
  } 
  
  
} 
import java.security.KeyManagementException;
import java.security.NoSuchAlgorithmException;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;

import javax.net.ssl.SSLContext;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

import org.apache.axis2.transport.http.HTTPConstants;
import org.apache.commons.httpclient.protocol.Protocol;
import org.apache.commons.httpclient.protocol.ProtocolSocketFactory;

import com.wondersgroup.cuteinfo.client.exchangeserver.exchangetransport.stub.ExchangeTransportServiceStub;
import com.wondersgroup.cuteinfo.client.exchangeserver.exchangetransport.stub2.ExchangeTransportServiceStub2;
import com.wondersgroup.cuteinfo.client.exchangeserver.transport.stub.MessageTransportServiceStub;

public class MySSLTrustManager {

	/**
	 * @author zjw 
	 * @descibes https 免证书验证
	 * @date 2017-12-16
	 */
	public static void trustAllCertsBySSL(MessageTransportServiceStub stu) {
		TrustManager[] trustAllCerts = new TrustManager[1];  
	    TrustManager tm = new MyTM();  
	    trustAllCerts[0] = tm;  
	    SSLContext sslctx;
		try {
			sslctx = SSLContext.getInstance("SSL");
			sslctx.init(null, trustAllCerts, null);  
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		stu._getServiceClient().getOptions().setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER,
			    new Protocol("https",(ProtocolSocketFactory)new MySSLProtocolSocketFactory(),443));
	}
	
	/**
	 * @author zjw 2017-12-16
	 * @descibers https 免证书验证
	 */
	public static void trustAllCertsBySSL(ExchangeTransportServiceStub stu) {
		TrustManager[] trustAllCerts = new TrustManager[1];  
		TrustManager tm = new MyTM();  
		trustAllCerts[0] = tm;  
		SSLContext sslctx;
		try {
			sslctx = SSLContext.getInstance("SSL");
			sslctx.init(null, trustAllCerts, null);  
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		stu._getServiceClient().getOptions().setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER,
				new Protocol("https",(ProtocolSocketFactory)new MySSLProtocolSocketFactory(),443));
	}
	
	/**
	 * @author zjw 2017-12-16
	 * @descibers https 免证书验证
	 */
	public static void trustAllCertsBySSL(ExchangeTransportServiceStub2 stu) {
		TrustManager[] trustAllCerts = new TrustManager[1];  
		TrustManager tm = new MyTM();  
		trustAllCerts[0] = tm;  
		SSLContext sslctx;
		try {
			sslctx = SSLContext.getInstance("SSL");
			sslctx.init(null, trustAllCerts, null);  
		} catch (NoSuchAlgorithmException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} catch (KeyManagementException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		}  
		stu._getServiceClient().getOptions().setProperty(HTTPConstants.CUSTOM_PROTOCOL_HANDLER,
				new Protocol("https",(ProtocolSocketFactory)new MySSLProtocolSocketFactory(),443));
	}
	
	static class MyTM implements TrustManager,X509TrustManager {  
	    public X509Certificate[] getAcceptedIssuers() {  
	        return null;  
	    }  
	  
	    public boolean isServerTrusted(X509Certificate[] certs) {  
	        return true;  
	    }  
	  
	    public boolean isClientTrusted(X509Certificate[] certs) {  
	        return true;  
	    }  
	  
	    public void checkServerTrusted(X509Certificate[] certs, String authType)  
	            throws CertificateException {  
	        return;  
	    }  
	  
	    public void checkClientTrusted(X509Certificate[] certs, String authType)  
	            throws CertificateException {  
	        return;  
	    }  
	}

}

 

关于自签名SSL证书

所谓自签名证书,就是自己颁发给自己的证书 ,所以颁证的主体是不可信任的 
自签证书是不会被浏览器信任的证书的,用户在访问自签证书时,浏览器会警告用户此证书不受信任,需要人工确认是否信任此证书。

既然自签证书是不可信任的,那为何还有人包括12306也在用自签证书呢? 
主要原因是: 
1)自签证书是免费的 
2)自签证书相对申请CA证书,流程更简单 
3)自签证书同样可以对数据进行加密 
4)自签证书的有效期可以设置很长,免去续签的麻烦 
5)自签证书更方便测试,比如说你想生成多少个不同服务器ip的都可以 
所以对于一些个人开发者来说使用自签证书可能会更方便,只要你能接受别人浏览你网站时弹出的提醒:不安全
 

自签名SSL证书的生成

自签证书虽然提示:不安全。但还是有很多上面已提到的好处,所以下面先说说自签证书的生成,主要使用Java JDK下的:keytool.exe 
1:先下载安装Java JDK:http://www.oracle.com/technetwork/java/javase/downloads/jdk8-downloads-2133151.html 
2:安装完后,根据实际的路径找到keytool.exe,如我的在此路径:C:\Program Files (x86)\Java\jdk1.8.0_101\bin\keytool.exe

3:生成keystore。打开命令行(cmd),去到keytool所在的路径,运行:

keytool -genkey -alias tomcat  -storetype PKCS12 -keyalg RSA -keysize 2048  -keystore d:\mykeystore\keystore.p12 -validity 3650  -ext san=ip:192.168.100.132 -dname "CN=garyyan, OU=mycompany, O=mycompany, L=gd, ST=gd, C=china"

此命令中间只需要输入密码,就能生成keystore,假设密码是:123456 
其中: 
1)keystore可理解为一个数据库,可以存很多个组数据。 
每组数据主要包含下面两种数据: 
a:密钥实体(Key entity)——密钥(secret key)又或者是私钥和配对公钥(采用非对称加密) 
b:可信任的证书实体(trusted certificate entries)——只包含公钥 
2)-keystore d:\mykeystore\keystore.p12,指定在d:\mykeystore(先要手动创建此文件夹),生成keystore:keystore.p12 
3)-alias tomcat,为其指明在keystore中的唯一的别名:tomcat ,因为keystore中可能还存有其它的别名,如:tomcat 2 
4)-storetype PKCS12指明密钥仓库类型是PKCS12 
5)-keyalg RSA,指定加密算法,本例中的采用通用的RAS加密算法 
6)-keysize 2048指定密钥的长度为2048 
7)-validity 3650 指定证书的有效期为3650天 
8)-ext san=ip:192.168.100.132请根据你的服务器的IP地址设置,如果不进行设置,客户端在访问的时候可能会报错 
9)-dname “CN=garyyan, OU=mycompany,O=mycompany,L=gd, ST=gd, C=china” 
其中:”CN=(名字与姓氏), OU=(组织单位名称), O=(组织名称), L=(城市或区域名称), ST=(州或省份名称), C=(单位的两字母国家代码)”,我在测试的过程中发现随便填就行

4:导出公钥证书(主要用于客户端): 
运行命令:

keytool -export -keystore d:\mykeystore\keystore.p12 -alias tomcat -file mycer.cer -storepass 123456

其中: 
1)-keystore d:\mykeystore\keystore.p12 是指上面的keystore文件 
2)-alias tomcat是指定别名为tomcat的那一组 
3)-file mycer.cer指定在当前目录生成名为mycer.cer的证书 
4)-storepass 123456是上面生成keystore 所用的密码
 

--END--

转载于:https://my.oschina.net/90888/blog/1591735

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值