0

0

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

巴扎黑

巴扎黑

发布时间:2016-12-20 15:08:39

|

2004人浏览过

|

来源于php中文网

原创

异常信息如下:

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库中

 

导入办法:

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

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

 

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

 

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

Originality AI
Originality AI

专门为网络出版商设计的抄袭和AI检测工具

下载

如果是在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

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[]{};  
            }  
        }  
          
      
    }

本站声明:本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系admin@php.cn

相关专题

更多
c++ 根号
c++ 根号

本专题整合了c++根号相关教程,阅读专题下面的文章了解更多详细内容。

22

2026.01.23

c++空格相关教程合集
c++空格相关教程合集

本专题整合了c++空格相关教程,阅读专题下面的文章了解更多详细内容。

24

2026.01.23

yy漫画官方登录入口地址合集
yy漫画官方登录入口地址合集

本专题整合了yy漫画入口相关合集,阅读专题下面的文章了解更多详细内容。

99

2026.01.23

漫蛙最新入口地址汇总2026
漫蛙最新入口地址汇总2026

本专题整合了漫蛙最新入口地址大全,阅读专题下面的文章了解更多详细内容。

132

2026.01.23

C++ 高级模板编程与元编程
C++ 高级模板编程与元编程

本专题深入讲解 C++ 中的高级模板编程与元编程技术,涵盖模板特化、SFINAE、模板递归、类型萃取、编译时常量与计算、C++17 的折叠表达式与变长模板参数等。通过多个实际示例,帮助开发者掌握 如何利用 C++ 模板机制编写高效、可扩展的通用代码,并提升代码的灵活性与性能。

15

2026.01.23

php远程文件教程合集
php远程文件教程合集

本专题整合了php远程文件相关教程,阅读专题下面的文章了解更多详细内容。

65

2026.01.22

PHP后端开发相关内容汇总
PHP后端开发相关内容汇总

本专题整合了PHP后端开发相关内容,阅读专题下面的文章了解更多详细内容。

61

2026.01.22

php会话教程合集
php会话教程合集

本专题整合了php会话教程相关合集,阅读专题下面的文章了解更多详细内容。

63

2026.01.22

宝塔PHP8.4相关教程汇总
宝塔PHP8.4相关教程汇总

本专题整合了宝塔PHP8.4相关教程,阅读专题下面的文章了解更多详细内容。

33

2026.01.22

热门下载

更多
网站特效
/
网站源码
/
网站素材
/
前端模板

精品课程

更多
相关推荐
/
热门推荐
/
最新课程
oracle基础视频教程
oracle基础视频教程

共31课时 | 6.6万人学习

jsp在线参考手册
jsp在线参考手册

共32课时 | 19.7万人学习

JAVA教程手册
JAVA教程手册

共70课时 | 49.9万人学习

关于我们 免责申明 举报中心 意见反馈 讲师合作 广告合作 最新更新
php中文网:公益在线php培训,帮助PHP学习者快速成长!
关注服务号 技术交流群
PHP中文网订阅号
每天精选资源文章推送

Copyright 2014-2026 https://www.php.cn/ All Rights Reserved | php.cn | 湘ICP备2023035733号