`
liulanghan110
  • 浏览: 1076774 次
  • 性别: Icon_minigender_1
  • 来自: 武汉
社区版块
存档分类
最新评论

httpclient向HTTPS发送数据建立SSL连接时的异常

    博客分类:
  • JAVA
阅读更多

异常信息如下:

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 factorytest.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

 

    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.SecureProtocolSocketFactory;  
      
    public class MySecureProtocolSocketFactory implements SecureProtocolSocketFactory {  
        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[]{};  
            }  
        }  
          
      
    }  
 
分享到:
评论
1 楼 Trinea 2013-08-28  
可通过客户端信任所有证书或是服务器端添加证书两种方式解决,具体原因分析及解决方式见:http://www.trinea.cn/android/android-java-https-ssl-exception-2/

相关推荐

    JAVA利用HttpClient进行HTTPS接口调用

    此外,还需要创建一个SSLConnectionSocketFactory,它是HttpClient中的关键组件,负责建立安全的SSL/TLS连接。 接下来,`HttpClientUtil.java`文件可能是实现HttpClient工具类,提供一个静态方法来创建和初始化...

    Java发 Https请求工具类 支持SSL

    7. **HttpClient库**: Java内置的`HttpURLConnection`可以发送HTTPS请求,但更高级的库如Apache HttpClient提供了更多功能,如连接池、重试策略等,对于复杂的应用场景更加适用。 8. **HTTPS连接的建立**: 包括握手...

    https发送post请求

    它使用SSL/TLS加密技术,在客户端和服务器之间建立加密连接。 2. **POST请求**:一种HTTP请求方法,用于向指定资源提交数据,通常用于创建新资源或更新现有资源。 #### 三、发送HTTPS POST请求的关键步骤 1. **...

    httpClient需要的jar包

    同时,它也可以处理HTTPS连接,配置SSL上下文以实现安全通信。 7. **异步编程**:HttpClient 4.5及以上版本引入了AsyncHttpClient,支持异步非阻塞I/O,适用于高并发场景。 8. **Cookie管理**:HttpClient有一个...

    httpclient3.1 javadoc chm版

    HttpClient 3.1支持连接池,可以复用已建立的连接,提高性能。使用HttpConnectionManager来管理连接池,如SingleClientConnManager或MultiThreadedHttpConnectionManager。 五、重定向处理 HttpClient可以自动处理...

    HttpClient 4.4英文版文档

    - **主机名验证**:演示了如何进行SSL连接的主机名验证。 #### 2.8 HttpClient代理配置 介绍了如何通过代理服务器发送HTTP请求。 ### 3. HTTP状态管理 #### 3.1 HTTP cookies 介绍了如何处理HTTP cookie。 #### ...

    httpclient4

    - **API调用**:对于RESTful API,HttpClient 是一个理想的客户端工具,可以方便地发送JSON或XML数据。 - **文件上传下载**:通过POST或PUT请求,HttpClient 可以实现文件的上传,通过GET请求实现文件的下载。 - ...

    httpclient-4.5.6.rar

    它支持 Keep-Alive 连接,能够重用已经建立的 TCP 连接,减少了网络延迟。 2. **认证与安全**:此版本加强了身份验证和安全特性,支持多种认证机制(如 Basic、Digest、NTLM 和 Kerberos),并提供了 TLS/SSL 支持...

    HttpClient_Demo

    6. **错误处理**:当请求失败时,可以通过捕获`IOException`和`HttpException`来处理异常,例如重试策略、错误信息的记录和反馈。 7. **HTTPS安全通信**:HttpClient支持HTTPS,通过设置`SSLContext`和`...

    httpclient4.5源码学习

    1. **执行流程**:从 `HttpClient.execute()` 方法开始,通过 `HttpRequestExecutor.execute()` 将请求发送到服务器,并接收响应。 2. **连接管理**:`PoolingHttpClientConnectionManager` 负责连接的创建、复用和...

    HTTPClient

    在使用SSL时,可能会遇到`SSLPeerUnverifiedException`异常,这是因为服务器证书未被验证。为了解决这个问题,可以配置信任所有证书的策略: ```java SSLContext sslContext = SSLContexts.custom() ....

    httpclient 查询股票信息

    在发送HTTP请求时,开发者可能会循环遍历这些代码,为每个代码构建特定的URL(通常包括股票代码和某种查询参数),然后使用HTTPClient发送请求。 在处理股票数据时,开发者可能会用到Java的CSV解析库,如OpenCSV或...

    httpclient4.5.6依赖的jar包(全)

    1. **连接管理**:HTTPClient 4.5.6引入了连接池,能够高效地复用TCP连接,减少了建立新连接的开销。`httpcomponents-client-4.5.6.jar`包含了`HttpClient`类和相关的连接管理类,如`...

    HttpClient jar包,快来拿呀

    - **HttpClient配置**:HttpClientBuilder允许自定义连接管理器、重试策略、SSL上下文等高级设置。 2. **连接管理**: - **PoolingHttpClientConnectionManager**:管理HTTP连接的池,提高性能和资源利用率。 - ...

    httpclient

    为了建立安全的连接,HttpClient支持使用SSL/TLS协议。 **2.7.2 与连接管理器集成** 套接字工厂可以与连接管理器集成,以便统一管理和配置所有连接。 **2.7.3 SSL/TLS定制** 可以根据需要对SSL/TLS协议进行定制,...

    HttpClient4.5.1手册

    - **安全套接层:** 在HTTPS连接中,使用SSL/TLS协议来加密传输数据。 - **与连接管理器的集成:** 连接套接字工厂与连接管理器协同工作,共同完成安全连接的建立。 - **SSL/TLS定制:** 可以根据具体需求配置SSL/...

    httpclient 4.5 api文档

    ### httpclient 4.5 API文档知识点概览 #### 一、基础知识 ##### 1.1 请求执行 **1.1.1 HTTP请求** - **定义**:HTTP客户端通过发送HTTP请求来与服务器进行交互。 - **组成**: - 方法(GET、POST等); - URI...

    最新官方资源httpclient-4.1.3.jar和httpcore-4.1.4.jar

    3. 安全性:在处理敏感数据时,确保使用HTTPS协议,并正确配置SSL/TLS。 4. 性能优化:根据实际需求调整HttpClient的配置参数,如连接超时时间、最大连接数等。 总的来说,HTTPClient和HTTPCore是Java进行HTTP通信...

    httpClient4 最新帮助文档

    - 使用`SSLContext`和`SSLSocketFactory`配置HTTPS连接。 - 配置信任管理器和证书,处理自签名证书或特定CA。 8. **性能优化**: - 使用连接池减少连接建立时间,提高效率。 - 使用线程池管理异步请求,避免...

Global site tag (gtag.js) - Google Analytics