zoukankan      html  css  js  c++  java
  • https请求出现Received fatal alert: handshake_failure异常解决

    1.简述

      使用Https请求知道链接时出现javax.net.ssl.SSLHandshakeException: Received fatal alert: handshake_failure异常,是因为ssl协议错误。

    2.解决方案

      主要是在创建SSLContext的时候指定TLS协议,就可以解决这个问题,使用的是httpclient-4.5.jar、httpcore-4.4.1.jar。

      出现异常示例代码如下

    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.ssl.SSLContextBuilder;
    import org.apache.http.util.EntityUtils;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            String url = "https://weather.com/weather/today/l/22.69,113.91?par=google";
            String result = "";
            CloseableHttpClient httpClient = null;
            try {
                SSLContextBuilder builder = new SSLContextBuilder();
                // 全部信任 不做身份鉴定
                builder.loadTrustMaterial(null, new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                        return true;
                    }
                });
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new String[] { "SSLv2Hello", "SSLv3", "TLSv1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
                Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build();
                PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
                cm.setMaxTotal(200);// max connection
                httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).setConnectionManagerShared(true).build();
                HttpGet httpGet = new HttpGet(url);
                RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();// 设置请求和传输超时时间
                httpGet.setConfig(requestConfig);
                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity resEntity = httpResponse.getEntity();
                result = EntityUtils.toString(resEntity);
            } catch (Exception e) {
                throw e;
            } finally {
                if (httpClient != null) {
                    httpClient.close();
                }
            }
            System.out.println(result);
        }
    }
    View Code

      第一种成功获取的示例代码如下

    import java.io.IOException;
    import java.net.URI;
    import javax.net.ssl.SSLContext;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.CloseableHttpResponse;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.util.EntityUtils;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            String url = "https://weather.com/weather/today/l/22.69,113.91?par=google";
            String result = null;
            HttpGet get = new HttpGet();
            CloseableHttpResponse res = null;
            CloseableHttpClient client = null;
            try {
                RequestConfig config = RequestConfig.custom().setConnectTimeout(10000).setSocketTimeout(12000).build();
                SSLContext sslContext = SSLContext.getInstance("TLSv1.2");
                sslContext.init(null,null,null);
                SSLContext.setDefault(sslContext);
                Registry<ConnectionSocketFactory> socketFactoryRegistry =
                        RegistryBuilder.<ConnectionSocketFactory>create()
                                .register("http", PlainConnectionSocketFactory.INSTANCE)
                                .register("https", new SSLConnectionSocketFactory(sslContext)).build();
                PoolingHttpClientConnectionManager mananger = new PoolingHttpClientConnectionManager(socketFactoryRegistry);
                mananger.setMaxTotal(100);
                mananger.setDefaultMaxPerRoute(20);
                client = HttpClients.custom().setConnectionManager(mananger).build();
                get.setConfig(config);
                get.setURI(new URI(url));
                res = client.execute(get);
                result = EntityUtils.toString(res.getEntity());
            } catch (Exception e) {
                e.printStackTrace();
            }finally {
                get.releaseConnection();
                try {
                    res.close();
                    client.close();
                } catch (IOException e1) {
                    e1.printStackTrace();
                }
            }
            System.out.println(result);
        }
    }
    View Code

      第二种成功获取的示例代码如下

    import java.security.cert.CertificateException;
    import java.security.cert.X509Certificate;
    import org.apache.http.HttpEntity;
    import org.apache.http.HttpResponse;
    import org.apache.http.client.config.RequestConfig;
    import org.apache.http.client.methods.HttpGet;
    import org.apache.http.config.Registry;
    import org.apache.http.config.RegistryBuilder;
    import org.apache.http.conn.socket.ConnectionSocketFactory;
    import org.apache.http.conn.socket.PlainConnectionSocketFactory;
    import org.apache.http.conn.ssl.NoopHostnameVerifier;
    import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
    import org.apache.http.conn.ssl.TrustStrategy;
    import org.apache.http.impl.client.CloseableHttpClient;
    import org.apache.http.impl.client.HttpClients;
    import org.apache.http.impl.conn.PoolingHttpClientConnectionManager;
    import org.apache.http.ssl.SSLContextBuilder;
    import org.apache.http.util.EntityUtils;
    
    public class Demo {
        public static void main(String[] args) throws Exception {
            String url = "https://weather.com/weather/today/l/22.69,113.91?par=google";
            String result = "";
            CloseableHttpClient httpClient = null;
            try {
                SSLContextBuilder builder = new SSLContextBuilder();
                // 全部信任 不做身份鉴定
                builder.loadTrustMaterial(null, new TrustStrategy() {
                    @Override
                    public boolean isTrusted(X509Certificate[] x509Certificates, String s) throws CertificateException {
                        return true;
                    }
                });
                SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(builder.build(), new String[] { "TLSv1", "TLSv1.2" }, null, NoopHostnameVerifier.INSTANCE);
                Registry<ConnectionSocketFactory> registry = RegistryBuilder.<ConnectionSocketFactory> create().register("http", new PlainConnectionSocketFactory()).register("https", sslsf).build();
                PoolingHttpClientConnectionManager cm = new PoolingHttpClientConnectionManager(registry);
                cm.setMaxTotal(200);// max connection
                httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).setConnectionManager(cm).setConnectionManagerShared(true).build();
                HttpGet httpGet = new HttpGet(url);
                RequestConfig requestConfig = RequestConfig.custom().setSocketTimeout(30000).setConnectTimeout(30000).build();// 设置请求和传输超时时间
                httpGet.setConfig(requestConfig);
                HttpResponse httpResponse = httpClient.execute(httpGet);
                HttpEntity resEntity = httpResponse.getEntity();
                result = EntityUtils.toString(resEntity);
            } catch (Exception e) {
                throw e;
            } finally {
                if (httpClient != null) {
                    httpClient.close();
                }
            }
            System.out.println(result);
        }
    }
    View Code

      第二种成功是因为去除了SSLv2Hello、SSLv3协议。

      注意:三个示例中的最后一个输出记得屏蔽,因为内容较多不屏蔽则会卡一会。

  • 相关阅读:
    未授权访问漏洞总结
    常见的端口速查
    Memcache未授权访问漏洞利用及修复
    Ubuntu 16.04 LTS安装Docker
    Ubuntu安装Python2+Python3
    不直接登录SharePoint服务器,通过远程直接部署WSP解决方案包
    SharePoint 2010 人员选择器搜索范围的限定
    SharePoint 2010 匿名访问开启后不能访问Allitems.aspx或DisplayForm.aspx
    博主跑路了
    【pwnable.tw】 alive_note
  • 原文地址:https://www.cnblogs.com/bl123/p/14977632.html
Copyright © 2011-2022 走看看