SSLException

来源:互联网 发布:centos打开端口命令 编辑:程序博客网 时间:2024/05/23 21:12

 

异常信息如下:

javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

 

原因:服务器的证书不被信任。一般是这样造成的。

使用KEYTOOL工具创建证书,然后用TOMCAT启动后,在浏览器打开网站时,会出现证书不被信任的提示。当然,利用HTTPCLIENT向服务端HTTPS发送数据时,HTTPCLIENT也会检测服务端的证书是否被信任,不被信任就抛出上面的异常。

解决办法有两种,一种是使证书被客户端信任。另一种是使用HTTPCLIENT发送数据时不检测服务器证书是否可信。

 

第一种办法,使证书被信任

 

找正规CA签发证书,或者自己签发证书(只能那一台客户机上可信)。找正规CA签发证书就不说了,自己签发证书呢,见我的其他文章。

 

我发现,自己签名的证书弄好之后,从客户端打开服务端地址时,不再提示上面的错误,但是还是不能发送数据。原因是什么呢?因为那台证书在客户端操作系统上可信,但是在JAVA的KEYSTORE里不可信,要把服务端的证书导入KEYSTORE库中

 

导入办法:

打开命令行窗口,并到<java-home>\lib\security\ 目录下,运行下面的命令:

keytool -import -noprompt -keystore cacerts -storepass changeit -alias yourEntry1 -file your.cer

 

最后一个是服务端导出的证书,其他可以默认。

 

要注意的是,如果客户端电脑上装有许多个JAVA版本,要确定你导入的证书的JAVA版本是你TOMCAT使用的那个,一般TOMCAT使用的是环境变量指向的那个JAVA版本。

如果是在ECLIPSE中建立的TOMCAT服务器,新建时会要你选择默认JRE还是指向的JAVA,这里一定要选指向刚才导入的那个JAVA的路径,不然,你导入的证书库也没效果。

 

第二种办法,使用HTTPCLIENT时不检测服务器证书是否可信

 

扩展HttpClient 类实现自动接受证书

 

因为这种方法自动接收所有证书,因此存在一定的安全问题,所以在使用这种方法前请仔细考虑您的系统的安全需求。具体的步骤如下:

 

•提供一个自定义的socket factory (test.MySecureProtocolSocketFactory )。这个自定义的类必须实现接口org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory ,在实现接口的类中调用自定义的X509TrustManager(test.MyX509TrustManager) ,这两个类可以在随本文带的附件中得到

•创建一个org.apache.commons.httpclient.protocol.Protocol 的实例,指定协议名称和默认的端口号

Protocol myhttps = new Protocol("https", new MySecureProtocolSocketFactory (), 443);

 

•注册刚才创建的https 协议对象

Protocol.registerProtocol("https ", myhttps);

 

•然后按照普通编程 方式打开https 的目标地址,代码如下:

MySecureProtocolSocketFactory.java

 

Java代码  收藏代码
  1. import java.io.IOException;    
  2. import java.net.InetAddress;    
  3. import java.net.InetSocketAddress;    
  4. import java.net.Socket;    
  5. import java.net.SocketAddress;    
  6. import java.net.UnknownHostException;    
  7. import java.security.KeyManagementException;    
  8. import java.security.NoSuchAlgorithmException;    
  9. import java.security.cert.CertificateException;    
  10. import java.security.cert.X509Certificate;    
  11.     
  12. import javax.net.SocketFactory;    
  13. import javax.net.ssl.SSLContext;    
  14. import javax.net.ssl.TrustManager;    
  15. import javax.net.ssl.X509TrustManager;    
  16.     
  17. import org.apache.commons.httpclient.ConnectTimeoutException;    
  18. import org.apache.commons.httpclient.params.HttpConnectionParams;    
  19. import org.apache.commons.httpclient.protocol.SecureProtocolSocketFactory;    
  20.     
  21. public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {    
  22.     private SSLContext sslcontext = null;    
  23.         
  24.     private SSLContext createSSLContext() {    
  25.         SSLContext sslcontext=null;    
  26.         try {    
  27.             sslcontext = SSLContext.getInstance("SSL");    
  28.             sslcontext.init(nullnew TrustManager[]{new TrustAnyTrustManager()}, new java.security.SecureRandom());    
  29.         } catch (NoSuchAlgorithmException e) {    
  30.             e.printStackTrace();    
  31.         } catch (KeyManagementException e) {    
  32.             e.printStackTrace();    
  33.         }    
  34.         return sslcontext;    
  35.     }    
  36.         
  37.     private SSLContext getSSLContext() {    
  38.         if (this.sslcontext == null) {    
  39.             this.sslcontext = createSSLContext();    
  40.         }    
  41.         return this.sslcontext;    
  42.     }    
  43.         
  44.     public Socket createSocket(Socket socket, String host, int port, boolean autoClose)    
  45.             throws IOException, UnknownHostException {    
  46.         return getSSLContext().getSocketFactory().createSocket(    
  47.                 socket,    
  48.                 host,    
  49.                 port,    
  50.                 autoClose    
  51.             );    
  52.     }    
  53.     
  54.     public Socket createSocket(String host, int port) throws IOException,    
  55.             UnknownHostException {    
  56.         return getSSLContext().getSocketFactory().createSocket(    
  57.                 host,    
  58.                 port    
  59.             );    
  60.     }    
  61.         
  62.         
  63.     public Socket createSocket(String host, int port, InetAddress clientHost, int clientPort)    
  64.             throws IOException, UnknownHostException {    
  65.         return getSSLContext().getSocketFactory().createSocket(host, port, clientHost, clientPort);    
  66.     }    
  67.     
  68.     public Socket createSocket(String host, int port, InetAddress localAddress,    
  69.             int localPort, HttpConnectionParams params) throws IOException,    
  70.             UnknownHostException, ConnectTimeoutException {    
  71.         if (params == null) {    
  72.             throw new IllegalArgumentException("Parameters may not be null");    
  73.         }    
  74.         int timeout = params.getConnectionTimeout();    
  75.         SocketFactory socketfactory = getSSLContext().getSocketFactory();    
  76.         if (timeout == 0) {    
  77.             return socketfactory.createSocket(host, port, localAddress, localPort);    
  78.         } else {    
  79.             Socket socket = socketfactory.createSocket();    
  80.             SocketAddress localaddr = new InetSocketAddress(localAddress, localPort);    
  81.             SocketAddress remoteaddr = new InetSocketAddress(host, port);    
  82.             socket.bind(localaddr);    
  83.             socket.connect(remoteaddr, timeout);    
  84.             return socket;    
  85.         }    
  86.     }    
  87.         
  88.     //自定义私有类    
  89.     private static class TrustAnyTrustManager implements X509TrustManager {    
  90.            
  91.         public void checkClientTrusted(X509Certificate[] chain, String authType) throws CertificateException {    
  92.         }    
  93.        
  94.         public void checkServerTrusted(X509Certificate[] chain, String authType) throws CertificateException {    
  95.         }    
  96.        
  97.         public X509Certificate[] getAcceptedIssuers() {    
  98.             return new X509Certificate[]{};    
  99.         }    
  100.     }    
  101.         
  102.     
  103. }    
------------------------------------------------
public DefaultHttpClient getNewHttpClient() {
try {
KeyStore trustStore = KeyStore.getInstance(KeyStore
.getDefaultType());
trustStore.load(null, null);


SSLSocketFactory sf = new SSLSocketFactoryEx(trustStore);
sf.setHostnameVerifier(SSLSocketFactory.ALLOW_ALL_HOSTNAME_VERIFIER);


HttpParams params = new BasicHttpParams();
HttpProtocolParams.setVersion(params, HttpVersion.HTTP_1_1);
HttpProtocolParams.setContentCharset(params, HTTP.UTF_8);


SchemeRegistry registry = new SchemeRegistry();
registry.register(new Scheme("http", PlainSocketFactory
.getSocketFactory(), 80));
registry.register(new Scheme("https", sf, 443));


ClientConnectionManager ccm = new ThreadSafeClientConnManager(
params, registry);


return new DefaultHttpClient(ccm, params);
} catch (Exception e) {
return new DefaultHttpClient();
}
}
 
原创粉丝点击