首页 > 编程语言 >解决远程调用三方接口:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException报错

解决远程调用三方接口:javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException报错

时间:2024-05-07 18:11:42浏览次数:46  
标签:java SSLHandshakeException sun OkHttpClient 报错 import new security public

一、前言

最近在对接腾讯会议API接口,在鉴权完成后开始调用对方的接口,在此过程中出现调用报错:javax.net.ssl.SSLHandshakeException。

二、出现原因

当你在进行https请求时,JDK中不存在三方服务的信任证书,导致出现错误javax.net.ssl.SSLHandshakeException:sun.security.validator.ValidatorException:PKIX路径构建失败。

三、解决方法

1、获取根证书安装证书到你的JRE的Java cacerts中(安装证书到PATHTOYOURJDK/JRE/lib目录/ cacerts中)。

2、忽略SSL证书的校验。

这里因为很多情况没有证书,所以采用第二种方案,在你的代码中进行忽略SSL证书校验。

四、代码

这里要区分你使用的是那种方式调用三方服务(RestTemplate 、OkHttpClient)。

1、RestTemplate

package com.hikvision.meeting.config;
 
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.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
import org.springframework.web.client.RestTemplate;
 
import javax.net.ssl.*;
import java.security.cert.CertificateException;
import java.security.cert.X509Certificate;
 
 
/**
 * @author dongliang7
 * @projectName 
 * @ClassName Config2RestTemplate.java
 * @description: 跳过证书效验
 * @createTime 2021年11月23日 09:59:00
 */
@Configuration
public class Config2RestTemplate {
 
    @Bean
    public RestTemplate restTemplate() throws Exception {
        TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
 
        SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
                .loadTrustMaterial(null, acceptingTrustStrategy)
                .build();
 
//        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
        SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(),
                // 指定TLS版本
                null,
                // 指定算法
                null,
                // 取消域名验证
                new HostnameVerifier() {
                    @Override
                    public boolean verify(String string, SSLSession ssls) {
                        return true;
                    }
                });
 
        CloseableHttpClient httpClient = HttpClients.custom()
                .setSSLSocketFactory(csf)
                .build();
 
        HttpComponentsClientHttpRequestFactory requestFactory =
                new HttpComponentsClientHttpRequestFactory();
 
        requestFactory.setHttpClient(httpClient);
        requestFactory.setReadTimeout(60 * 1000);// ms
        requestFactory.setConnectTimeout(60 * 1000);// ms
        // 该代码的意思是请求工厂类是否应用缓冲请求正文内部,默认值为true,当post或者put大文件的时候会造成内存溢出情况,设置为false将数据直接流入底层HttpURLConnection
        requestFactory.setBufferRequestBody(false);
        RestTemplate restTemplate = new RestTemplate(requestFactory);
        return restTemplate;
    }
 
    /**
     * 跳过证书效验的sslcontext
     *
     * @return
     * @throws Exception
     */
    private static SSLContext createIgnoreVerifySSL() throws Exception {
        SSLContext sc = SSLContext.getInstance("TLS");
 
        // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
        X509TrustManager trustManager = new X509TrustManager() {
            @Override
            public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }
 
            @Override
            public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate,
                                           String paramString) throws CertificateException {
            }
 
            @Override
            public X509Certificate[] getAcceptedIssuers() {
                return null;
            }
        };
        sc.init(null, new TrustManager[] { trustManager }, null);
        return sc;
    }
}

2、OkHttpClient

package com.tencent.wemeet.gateway.restapisdk.util;
 
import lombok.extern.slf4j.Slf4j;
import okhttp3.OkHttpClient;
 
import javax.net.ssl.*;
import java.security.KeyStore;
import java.security.NoSuchAlgorithmException;
import java.util.Arrays;
import java.util.concurrent.TimeUnit;
 
/**
 * @author dongliang7
 * @projectName tenxun-meeting-api
 * @ClassName SSLSocketClient.java
 * @description: 创建 OkHttpClient 不进行SSL(证书)验证
 * @createTime 2021年11月19日 09:50:00
 */
@Slf4j
public class SSLSocketClient {
 
    public static OkHttpClient getUnsafeOkHttpClient() {
        try {
            // 创建不验证证书链的信任管理器
            final TrustManager[] trustAllCerts = new TrustManager[]{
                    new X509TrustManager() {
                        @Override
                        public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
                        @Override
                        public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
                        @Override
                        public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                            return new java.security.cert.X509Certificate[]{};
                        }
                    }
            };
            if (trustAllCerts.length != 1 || !(trustAllCerts[0] instanceof X509TrustManager)) {
                throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustAllCerts));
            }
            X509TrustManager x509TrustManager = (X509TrustManager) trustAllCerts[0];
 
            // 安装全信任信任管理器
            final SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            // 使用我们完全信任的管理器创建 ssl 套接字工厂
            final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
 
            OkHttpClient.Builder builder = new OkHttpClient.Builder()
                    .connectTimeout(60 , TimeUnit.SECONDS).readTimeout(60 , TimeUnit.SECONDS).writeTimeout(120 , TimeUnit.SECONDS);
            builder.sslSocketFactory(sslSocketFactory , x509TrustManager);
            builder.hostnameVerifier(new HostnameVerifier() {
                @Override
                public boolean verify(String hostname, SSLSession session) {
                    return true;
                }
            });
            OkHttpClient okHttpClient = builder.build();
            return okHttpClient;
        } catch (Exception e) {
            log.error("创建OkHttpClient不进行SSL(证书)验证失败:{}", e.getMessage());
            throw new RuntimeException(e);
        }
    }
}

获取OkHttpClient :

//创建 OkHttpClient 不进行SSL(证书)验证
    private static final OkHttpClient okHttpClient = SSLSocketClient.getUnsafeOkHttpClient();

在minio中的运用

 minioClient = MinioClient.builder()
                        .endpoint(minioUrl, Integer.parseInt(minioUrl.substring(minioUrl.lastIndexOf(":")+1,minioUrl.length()-1)),true)
                        .credentials(minioName, minioPass)
                        .httpClient(okHttpClient)
                        .build();

 

标签:java,SSLHandshakeException,sun,OkHttpClient,报错,import,new,security,public
From: https://www.cnblogs.com/luxj/p/18178106

相关文章

  • 关于FreeSql报错System.Exception: SQL logic error near " ": syntax error
    ps:不要什么都存数据库。。。遇到一个BUG,调试了好久没找到原因,后来打印了sql语句,问题出在msg.Msg字段的保存,如下:msg.Msg是一串JSON字符串保存的时候,FreeSql会解析成:因为特殊字符,导致保存失败。 ......
  • @RefreshScope导致xxl-job jobhandler naming conflicts项目启动报错
    问题项目里使用xxl-job定时任务框架,某个任务定义如下:@Slf4j@RefreshScope@Component@JobHandler("xxxTask")publicclassXxxTaskextendsIJobHandler{@Value("${xxx.enable:false}")privatebooleanenable;@OverridepublicReturnT<S......
  • SSH远程连接时报错提示Permission denied (publickey).的解决方法
    1.发现问题在Linux终端使用sshroot@server_ip来连接到远程服务器时,出现Permissiondenied(publickey).提示2.分析问题远程主机禁用了ssh密码登录权限本地访问远程主机的公钥没有添加或者被取消(无法认证)本地生成的一对秘钥,私钥~/.ssh/id_rsa和公钥~/.ssh/id_rsa.pub。......
  • jmap使用报错Doesn't appear to be a HotSpot VM (could not find symbol "gHotSpotVM
    报错场景问题原因服务器上装了jdk,按理来说jmap是自带了的,可以直接使用,根据情况来看是装了jmap但是无法正常使用,推测是版本的问题导致解决方式指定jdk自带的jmap工具1.查看当前java的环境变量echo$JAVA_HOME2.配置jdk自带工具的环境变量exportPATH=$JAVA_HOME/bin:$P......
  • 解决报错:Could not set property 'id' of 'class com.north.domain.Book' with value
    报错原因问题描述:因为MyBatis-Plus默认的id自增策略使用的雪花算法org.mybatis.spring.MyBatisSystemException:nestedexceptionisorg.apache.ibatis.reflection.ReflectionException:Couldnotsetproperty'id'of'classcom.north.domain.Book'withvalue'1......
  • vue-i18n的9以上的版本中@被用作特殊字符处理,直接用会报错
    vue3项目中使用vue-i18n的9以上的版本实现国际化,使用过程中出现报错:国际化使用 "validation.regExp.name":"仅允许输入字母、数字与_.@字符"报如下错误 Messagecompilationerror:Invalidlinkedformat1|仅允许输入字母、数字与_.@字符Messagecompilationerror:Un......
  • Less17基于报错的字符型注入
    Less17基于报错的字符型注入打开环境是一个密码重置页面在用户名栏输入各种语句都无效,遂审计源码functioncheck_input($value) { if(!empty($value)) { //truncation(seecomments) $value=substr($value,0,15); } //Stripslashesifmagicquotesenabled......
  • Mac更新python3.12 解决pip3安装报错
    Mac使用homebrew更新了python3.12,删除了以前的版本和pip3安装软件时候报错。error:externally-managed-environment×Thisenvironmentisexternallymanaged╰─>ToinstallPythonpackagessystem-wide,trybrewinstallxyz,wherexyzisthepackageyouare......
  • 报错“ opensslErrorStack: [ 'error:03000086:digital envelope routines::initiali
    报错“ opensslErrorStack:['error:03000086:digitalenveloperoutines::initializationerror']”报错信息前端启动项目报错,报错信息如下:$yarnstartyarnrunv1.22.21$cross-envUMI_ENV=devumidevBrowserslist:caniuse-liteisoutdated.Pleaserun:npx......
  • 在Docker内部使用gdb调试器报错-Operation not permitted
    在docker内部使用gdb调试时刻遇到了gdb如下报错信息:warning:Errordisablingaddressspacerandomization:Operationnotpermitted原因地址随机化是linux一项安全特性,它允许内核进程启动每次加载库的时候都在随机化的分布在进程虚拟内存地址空间上(早期固定的库要加载......