`
hujin1979
  • 浏览: 80190 次
  • 性别: Icon_minigender_1
  • 来自: 广州
社区版块
存档分类
最新评论

Java的HttpClient如何去支持无证书访问https

 
阅读更多

项目里需要访问其他接口,通过http/https协议。我们一般是用HttpClient类来实现具体的http/https协议接口的调用。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=http://www.xxx.com/xxx;

// Init a HttpMethod
HttpMethod get = new GetMethod(url);
get.setDoAuthentication(true);
get.getParams().setParameter(HttpMethodParams.RETRY_HANDLER, new DefaultHttpMethodRetryHandler(1, false));

// Call http interface
try {
    client.executeMethod(get);

    // Handle the response from http interface
    InputStream in = get.getResponseBodyAsStream();
    SAXReader reader = new SAXReader();
    Document doc = reader.read(in);
} finally {
    // Release the http connection
    get.releaseConnection();
}

以上代码在通过普通的http协议是没有问题的,但如果是https协议的话,就会有证书文件的要求了。一般情况下,是这样去做的。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;

if (url.startsWith("https:")) {
    System.setProperty("javax.net.ssl.trustStore", "/.sis.cer");
    System.setProperty("javax.net.ssl.trustStorePassword", "public");
}

......

于是,这里就需要事先生成一个.sis.cer的文件,生成这个文件的方法一般是先通过浏览器访问https://,导出证书文件,再用JAVA keytool command 生成证书

# $JAVA_HOME/bin/keytool -import -file sis.cer -keystore .sis.cer

但这样做,一比较麻烦,二来证书也有有效期,过了有效期之后,又需要重新生成一次证书。如果能够避开生成证书文件的方式来使用https的话,就比较好了。

还好,在最近的项目里,我们终于找到了方法。

// Init a HttpClient
HttpClient client = new HttpClient();
String url=https://www.xxx.com/xxx;

if (url.startsWith("https:")) {
    this.supportSSL(url, client);
}

......

这里用到了supportSSL(url, client)这个方法,看看这个方法是如何实现的。

private void supportSSL(String url, HttpClient client) {
        if(StringUtils.isBlank(url)) {
            return;
        }
        String siteUrl = StringUtils.lowerCase(url);
        if (!(siteUrl.startsWith("https"))) {
            return;
        }
       
        try {
           setSSLProtocol(siteUrl, client);
        } catch (Exception e) {
            logger.error("setProtocol error ", e);
        }
        Security.setProperty( "ssl.SocketFactory.provider",
        "com.tool.util.DummySSLSocketFactory");

    }

private static void setSSLProtocol(String strUrl, HttpClient client) throws Exception {
       
        URL url = new URL(strUrl);
        String host = url.getHost();
        int port = url.getPort();

        if (port <= 0) {
            port = 443;
        }
        ProtocolSocketFactory factory = new SSLSocketFactory();
        Protocol authhttps = new Protocol("https", factory, port);
        Protocol.registerProtocol("https", authhttps);
        // set https protocol
        client.getHostConfiguration().setHost(host, port, authhttps);
    }

在supportSSL方法里,调用了Security.setProperty( "ssl.SocketFactory.provider",
        "com.tool.util.DummySSLSocketFactory");

那么这个com.tool.util.DummySSLSocketFactory是这样的:

 

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

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

}

分享到:
评论

相关推荐

    java实现读取证书访问https接口

    本篇文章将深入探讨如何在Java中实现读取不同格式(如cer、der、crt)的证书,以及如何使用这些证书访问HTTPS接口并获取返回数据。 首先,我们需要了解证书的基本概念。证书通常包含了公钥和一些身份信息,由受信任...

    httpclient访问需要客户端认证数字证书的https接口的处理方法

    默认的`SSLProtocolSocketFactory`并不支持客户端证书,所以我们需要创建一个扩展,覆盖其`createSocket()`方法,以便在建立连接时设置客户端证书。在这个自定义实现中,你需要加载之前安装的客户端证书和私钥,然后...

    HttpClient4.5 实现https忽略SSL证书验证

    使用HttpClient4.5实现https请求忽略SSL证书验证工具类

    httpclient来进行https访问

    要使`httpclient`支持HTTPS访问,首先需要配置SSL上下文。这通常涉及到证书管理、密钥存储以及信任管理等环节。 ### 关键技术细节 #### 3.1 配置SSL上下文 在`httpclient`中使用HTTPS,首先要解决的是SSL上下文的...

    Android使用HttpClient和HttpsUrlConnection两种方式访问https网站

    本文将详细介绍如何使用`HttpClient`和`HttpsURLConnection`两种方式来访问HTTPS网站,包括验证证书和不验证证书的实现方法。 ### 1. Android中的HttpClient `HttpClient`是Apache提供的一种HTTP客户端库,它支持...

    httpclient4.5 绕过ssl认证文件访问

    本篇文章将详细讲解如何在HTTPClient 4.5版本中绕过SSL(Secure Sockets Layer)认证,实现对HTTPS网站的访问。 首先,了解SSL/TLS(Transport Layer Security)协议的重要性。SSL/TLS是网络安全传输的标准,它通过...

    Java Https请求,跳过证书,直接访问

    至于提到的"相关jar包全有",这可能指的是用于处理HTTPS请求和SSL连接的Java标准库(如`javax.net.ssl.*`)以及其他可能需要的第三方库,如Apache HttpClient。"TestHttp"可能是一个测试HTTP请求的Java类或文件,你...

    使用httpclient无需证书调用https的示例(java调用https)

    以下是一个使用HttpClient进行无证书验证调用HTTPS的示例。 首先,我们需要创建一个自定义的`SSLSocketFactory`,该工厂会忽略证书验证。这通常不推荐用于生产环境,因为它可能导致安全漏洞,但在测试或调试时非常...

    使用httpClient访问https+443端口号。

    标题中的“使用httpClient访问https+443端口号”指的是使用Apache HttpClient库来发起HTTPS(安全超文本传输协议)请求,目标服务器的默认端口是443。HTTPS是一种基于SSL/TLS的安全通信协议,用于在客户端和服务器...

    java使用HttpClient通过url下载文件到本地

    HttpClient是一个Java库,支持HTTP/1.1协议以及部分HTTP/2特性。它提供了一组高级API,用于处理HTTP请求和响应,包括重试、连接管理、超时设置等。对于网络编程,HttpClient是一个高效且灵活的选择。 2. **Eclipse...

    java访问https网址下载文件(含证书)

    当你访问HTTPS站点时,Java默认的TrustStore可能不包含特定服务器的证书,因此需要自定义SSL上下文。首先,你需要将服务器的证书导入到一个信任库文件(如JKS或PKCS12格式),然后创建一个`SSLContext`对象,并设置...

    JAVA利用HttpClient进行HTTPS接口调用的方法

    Java中使用HttpClient进行HTTPS接口调用的方法是通过继承DefaultHttpClient类,忽略证书校验过程。首先,创建一个SSLClient类,继承DefaultHttpClient类,并在构造函数中初始化SSLContext和TrustManager。然后,使用...

    httpclient4.1访问https的配置方法

    【标题】:“httpclient4.1访问https的配置方法” 【描述】:“本教程将指导你如何利用Apache HttpClient 4.1实现对HTTPS服务的访问,首先需要在Tomcat服务器上配置SSL支持。我们将涵盖SSL证书的生成、Tomcat服务器...

    Java 生成证书工具类 https

    java生成https安全证书,解决httpClient访问https出错 编译:javac InstallCert.java 运行:java InstallCert 要访问的网址 结果:Enter certificate to add to trusted keystore or 'q' to quit: [1] 输入1确认生成...

    使用httpclient访问servlet

    如果Servlet需要HTTPS(SSL/TLS)加密,HttpClient需要配置SSLContext和TrustStrategy,处理证书和信任问题。 10. **最佳实践**: - 关闭响应实体和HttpClient实例以释放资源。 - 避免长时间持有HttpClient实例...

    基于HttpClient 4.3的可访问自签名HTTPS站点的新版工具类

    另外在项目中正好需要访问https协议的接口,而对应的服务器没有购买商业CA颁发的正式受信证书,只是做了个自签名(联想一下12306网站购票时提示的那个警告信息),默认情况下通过HttpClient访问会抛出异常。...

    httpClient,JAVA访问http request response

    在JAVA中使用HttpClient访问HTTP请求并处理response,涉及到的主要知识点包括: 1. **HttpClient的基本使用**: - 创建HttpClient实例:通常使用`HttpClientBuilder`或`HttpClients`类创建HttpClient对象。 - ...

    HttpClient依赖jar包.zip

    4. **支持SSL/TLS**:HttpClient内置了对HTTPS的支持,可以处理SSL证书验证,确保数据传输的安全性。 5. **重试策略**:当网络不稳定或服务器短暂故障时,HttpClient可以设置重试策略,自动处理请求失败的情况。 6...

    keytool httpclient https所需jar包

    在使用这些JAR文件时,你需要将它们添加到你的项目类路径中,以便你的程序能够访问和使用`keytool`和`httpclient`的相关功能。如果你正在使用Maven或Gradle构建系统,你可以通过在你的构建配置文件中声明依赖来引入...

    java根证书认证实现https访问

    在Java中实现根证书认证以安全地访问HTTPS服务是一个关键的步骤,特别是在处理敏感数据或者进行服务器间通信时。HTTPS协议提供了对传输数据的加密,确保了数据在互联网上的完整性和机密性。本篇文章将深入探讨如何在...

Global site tag (gtag.js) - Google Analytics