Java中get/post的https请求忽略ssl证书认证浅析

 更新时间:2024年01月03日 08:30:26   作者:醉酒de李白  
因为Java在安装的时候,会默认导入某些根证书,所以有些网站不导入证书,也可以使用Java进行访问,这篇文章主要给大家介绍了关于Java中get/post的https请求忽略ssl证书认证的相关资料,需要的朋友可以参考下

需求

最近在负责一个对接第三方服务的事情,在对接期间,因为第三方服务为https的请求,众所周知,请求https请求会使用本地的证书公钥去访问服务SSL证书,应我本地并没有对应的SSL证书,所以请求不到服务,请求接口时报如下错误。翻阅资源发现是可以 忽略SSL认证的。

  • unable to find valid certification path to requested target

工具类

import org.apache.http.client.HttpClient;
import org.apache.http.conn.ssl.NoopHostnameVerifier;
import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
import org.apache.http.impl.client.CloseableHttpClient;
import org.apache.http.impl.client.HttpClients;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.http.converter.StringHttpMessageConverter;
import org.springframework.web.client.RestTemplate;
import java.nio.charset.StandardCharsets;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
import javax.net.ssl.HostnameVerifier;
import javax.net.ssl.HttpsURLConnection;
import javax.net.ssl.SSLContext;
import javax.net.ssl.SSLSession;
import javax.net.ssl.TrustManager;
import javax.net.ssl.X509TrustManager;

public class SslUtils {
    private static void trustAllHttpsCertificates() throws Exception {
        TrustManager[] trustAllCerts = new TrustManager[1];
        TrustManager tm = new miTM();
        trustAllCerts[0] = tm;
        SSLContext sc = SSLContext.getInstance("SSL");
        sc.init(null, trustAllCerts, null);
        HttpsURLConnection.setDefaultSSLSocketFactory(sc.getSocketFactory());
    }

    static class miTM implements TrustManager, X509TrustManager {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return null;
        }

        public boolean isServerTrusted(X509Certificate[] certs) {
            return true;
        }

        public boolean isClientTrusted(X509Certificate[] certs) {
            return true;
        }

        @Override
        public void checkServerTrusted(X509Certificate[] certs, String authType) throws CertificateException {
            return;
        }

        @Override
        public void checkClientTrusted(X509Certificate[] certs, String authType) throws CertificateException {
            return;
        }
    }

    /**
     * 忽略HTTPS请求的SSL证书,必须在openConnection之前调用
     *
     * @throws Exception
     */
    public static void ignoreSsl() throws Exception {
        HostnameVerifier hv = new HostnameVerifier() {
            @Override
            public boolean verify(String urlHostName, SSLSession session) {
                System.out.println("Warning: URL Host: " + urlHostName + " vs. " + session.getPeerHost());
                return true;
            }
        };
        trustAllHttpsCertificates();
        HttpsURLConnection.setDefaultHostnameVerifier(hv);
    }

    /**
     * 避免HttpClient的”SSLPeerUnverifiedException: peer not authenticated”异常
     * <p>
     * 不用导入SSL证书
     *
     * @param base
     * @return
     */
    public static HttpClient wrapClient(HttpClient base) {
        try {
            SSLContext ctx = SSLContext.getInstance("TLS");
            X509TrustManager tm = new X509TrustManager() {
                @Override
                public X509Certificate[] getAcceptedIssuers() {
                    return null;
                }
                @Override
                public void checkClientTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
                @Override
                public void checkServerTrusted(X509Certificate[] arg0, String arg1) throws CertificateException {}
            };
            ctx.init(null, new TrustManager[]{tm}, null);
            SSLConnectionSocketFactory ssf = new SSLConnectionSocketFactory(ctx, NoopHostnameVerifier.INSTANCE);
            CloseableHttpClient httpclient = HttpClients.custom().setSSLSocketFactory(ssf).build();
            return httpclient;
        } catch (Exception ex) {
            ex.printStackTrace();
            return HttpClients.createDefault();
        }
    }

    /**
     * 跳过证书效验的sslcontext
     *
     * @return
     * @throws Exception
     */
    private static SSLContext createIgnoreVerifySSL() throws Exception {
        SSLContext sc = SSLContext.getInstance("TLS");

        // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }

            @Override
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sc.init(null, new TrustManager[] { trustManager }, null);
        return sc;
    }

    /**
     * 构造RestTemplate
     *
     * @return
     * @throws Exception
     */
    public static RestTemplate getRestTemplate() throws Exception {
        HttpComponentsClientHttpRequestFactory factory = new HttpComponentsClientHttpRequestFactory();
        // 超时
//        factory.setConnectionRequestTimeout(5000);
//        factory.setConnectTimeout(5000);
//        factory.setReadTimeout(5000);
        SSLConnectionSocketFactory sslsf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(),
                // 指定TLS版本
                null,
                // 指定算法
                null,
                // 取消域名验证
                new HostnameVerifier() {
                    @Override
                    public boolean verify(String string, SSLSession ssls) {
                        return true;
                    }
                });
        CloseableHttpClient httpClient = HttpClients.custom().setSSLSocketFactory(sslsf).build();
        factory.setHttpClient(httpClient);
        RestTemplate restTemplate = new RestTemplate(factory);
        // 解决中文乱码问题
        restTemplate.getMessageConverters().set(1, new StringHttpMessageConverter(StandardCharsets.UTF_8));
        return restTemplate;
    }
}

使用方法

 @Override
    public void completionIndexPushToODS(List<Bean> data) throws Exception {
        try {
        	//请求地址
            String url ="https://.....";
            //请求参数
            String requestData = JSON.toJSONString(data);
            System.out.println("请求参数:" + requestData);

            RestTemplate restTemplate;
            if (flag) {
            	//HTTP绕过SSL证书认证
                restTemplate = SslUtils.getRestTemplate();
            } else {
            	//普通请求方式
                restTemplate = new RestTemplate();
            }
            //自定义header传输信息(根据自己的需求设置)
            HttpHeaders httpHeaders = new HttpHeaders();
            httpHeaders.setContentType(MediaType.APPLICATION_JSON_UTF8);
            
            HttpEntity<MultiValueMap<String, String>> httpEntity = new HttpEntity(JSON.toJSON(data), httpHeaders);
            URI uri = new URI(url);
            System.out.println("开始请求");
            //POST返回字节方式
            byte[] response = restTemplate.postForObject(uri, httpEntity, byte[].class);
           	//GET请求返回字符
            //String request = restTemplate.getForObject(uri, String.class);

            System.out.println("请求结束");
            if (response == null) {
                System.out.println("返回值为空");
            }
            String result = new String(response, "utf-8");
            System.out.println("返回结果:" + result);
        } catch (Exception e) {
            e.printStackTrace();
        }
    }

总结 

到此这篇关于Java中get/post的https请求忽略ssl证书认证的文章就介绍到这了,更多相关Java https请求忽略ssl证书认证内容请搜索脚本之家以前的文章或继续浏览下面的相关文章希望大家以后多多支持脚本之家!

相关文章

  • 详解mybatis中的if-else的嵌套使用

    详解mybatis中的if-else的嵌套使用

    本文主要介绍了mybatis中的if-else的嵌套使用,文中通过示例代码介绍的非常详细,对大家的学习或者工作具有一定的参考学习价值,需要的朋友们下面随着小编来一起学习学习吧
    2022-07-07
  • Java递归造成的堆栈溢出问题及解决方案

    Java递归造成的堆栈溢出问题及解决方案

    在Java中,递归造成的堆栈溢出问题通常是因为递归调用的深度过大,导致调用栈空间不足,解决这类问题的一种常见方法是使用非递归的方式重写算法,即使用迭代替代递归,需要的朋友可以参考下
    2024-08-08
  • Java中使用正则表达式的一个简单例子及常用正则分享

    Java中使用正则表达式的一个简单例子及常用正则分享

    这篇文章主要介绍了Java中使用正则表达式的一个简单例子及常用正则分享,本文用一个验证Email的例子讲解JAVA中如何使用正则,并罗列了一些常用的正则表达式,需要的朋友可以参考下
    2015-06-06
  • 一篇文章带你了解Maven的继承和聚合

    一篇文章带你了解Maven的继承和聚合

    这篇文章主要为大家介绍了Maven的继承和聚合,具有一定的参考价值,感兴趣的小伙伴们可以参考一下,希望能够给你带来帮助
    2022-01-01
  • Java实现添加页码到PDF文档

    Java实现添加页码到PDF文档

    页码可以清楚了解总页数、定位页数快速寻找自己所要的文段、打印时不会分不清头中尾。今天这篇文章就将介绍如何通过Java代码,以编程的方式将添加页码到PDF文档,需要的可以参考一下
    2023-04-04
  • IntelliJ IDEA创建maven多模块项目(图文教程)

    IntelliJ IDEA创建maven多模块项目(图文教程)

    这篇文章主要介绍了IntelliJ IDEA创建maven多模块项目(图文教程),非常具有实用价值,需要的朋友可以参考下
    2017-09-09
  • Java 数据结构与算法系列精讲之排序算法

    Java 数据结构与算法系列精讲之排序算法

    排序算法是《数据结构与算法》中最基本的算法之一。排序算法可以分为内部排序和外部排序,内部排序是数据记录在内存中进行排序,而外部排序是因排序的数据很大,一次不能容纳全部的排序记录,在排序过程中需要访问外存
    2022-02-02
  • java实现图的邻接表存储结构的两种方式及实例应用详解

    java实现图的邻接表存储结构的两种方式及实例应用详解

    这篇文章主要介绍了java实现图的邻接表存储结构的两种方式及实例应用详解,邻接表构建图是必须需要一个Graph对象,也就是图对象!该对象包含属性有:顶点数、边数以及图的顶点集合,需要的朋友可以参考下
    2019-06-06
  • Spring超详细讲解IOC与解耦合

    Spring超详细讲解IOC与解耦合

    IoC就是比方说有一个类,我们想要调用类里面的方法(不是静态方法),就要创建该类的对象,使用对象调用方法来实现。但对于Spring来说,Spring创建对象的过程,不是在代码里面实现的,而是交给Spring来进行配置实现的
    2022-08-08
  • Java数据结构之线段树详解

    Java数据结构之线段树详解

    线段树是一种二叉搜索树,与区间树相似,它将一个区间划分成一些单元区间,每个单元区间对应线段树中的一个叶结点。本文将介绍线段树的Java实现代码,需要的可以参考一下
    2022-01-01

最新评论