• 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协议。

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

  • 相关阅读:
    STM32 F4 DAC DMA Waveform Generator
    STM32 F4 General-purpose Timers for Periodic Interrupts
    Python第十四天 序列化 pickle模块 cPickle模块 JSON模块 API的两种格式
    Python第十三天 django 1.6 导入模板 定义数据模型 访问数据库 GET和POST方法 SimpleCMDB项目 urllib模块 urllib2模块 httplib模块 django和web服务器整合 wsgi模块 gunicorn模块
    查看SQL Server服务运行帐户和SQL Server的所有注册表项
    Pycharm使用技巧(转载)
    SQL Server 2014内存优化表的使用场景
    Python第十天 print >> f,和fd.write()的区别 stdout的buffer 标准输入 标准输出 从控制台重定向到文件 标准错误 重定向 输出流和输入流 捕获sys.exit()调用 optparse argparse
    Python第七天 函数 函数参数 函数里的变量 函数返回值 多类型传值 函数递归调用 匿名函数 内置函数
    Python第六天 类型转换
  • 原文地址:https://www.cnblogs.com/bl123/p/14977632.html
Copyright © 2020-2023  润新知