当前位置:   article > 正文

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

javax.net.ssl.sslhandshakeexception

一、前言

最近在对接腾讯会议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

  1. package com.hikvision.meeting.config;
  2. import org.apache.http.conn.ssl.SSLConnectionSocketFactory;
  3. import org.apache.http.conn.ssl.TrustStrategy;
  4. import org.apache.http.impl.client.CloseableHttpClient;
  5. import org.apache.http.impl.client.HttpClients;
  6. import org.springframework.context.annotation.Bean;
  7. import org.springframework.context.annotation.Configuration;
  8. import org.springframework.http.client.HttpComponentsClientHttpRequestFactory;
  9. import org.springframework.web.client.RestTemplate;
  10. import javax.net.ssl.*;
  11. import java.security.cert.CertificateException;
  12. import java.security.cert.X509Certificate;
  13. /**
  14. * @author dongliang7
  15. * @projectName
  16. * @ClassName Config2RestTemplate.java
  17. * @description: 跳过证书效验
  18. * @createTime 2021年11月23日 09:59:00
  19. */
  20. @Configuration
  21. public class Config2RestTemplate {
  22. @Bean
  23. public RestTemplate restTemplate() throws Exception {
  24. TrustStrategy acceptingTrustStrategy = (X509Certificate[] chain, String authType) -> true;
  25. SSLContext sslContext = org.apache.http.ssl.SSLContexts.custom()
  26. .loadTrustMaterial(null, acceptingTrustStrategy)
  27. .build();
  28. // SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(sslContext);
  29. SSLConnectionSocketFactory csf = new SSLConnectionSocketFactory(createIgnoreVerifySSL(),
  30. // 指定TLS版本
  31. null,
  32. // 指定算法
  33. null,
  34. // 取消域名验证
  35. new HostnameVerifier() {
  36. @Override
  37. public boolean verify(String string, SSLSession ssls) {
  38. return true;
  39. }
  40. });
  41. CloseableHttpClient httpClient = HttpClients.custom()
  42. .setSSLSocketFactory(csf)
  43. .build();
  44. HttpComponentsClientHttpRequestFactory requestFactory =
  45. new HttpComponentsClientHttpRequestFactory();
  46. requestFactory.setHttpClient(httpClient);
  47. requestFactory.setReadTimeout(60 * 1000);// ms
  48. requestFactory.setConnectTimeout(60 * 1000);// ms
  49. // 该代码的意思是请求工厂类是否应用缓冲请求正文内部,默认值为true,当post或者put大文件的时候会造成内存溢出情况,设置为false将数据直接流入底层HttpURLConnection
  50. requestFactory.setBufferRequestBody(false);
  51. RestTemplate restTemplate = new RestTemplate(requestFactory);
  52. return restTemplate;
  53. }
  54. /**
  55. * 跳过证书效验的sslcontext
  56. *
  57. * @return
  58. * @throws Exception
  59. */
  60. private static SSLContext createIgnoreVerifySSL() throws Exception {
  61. SSLContext sc = SSLContext.getInstance("TLS");
  62. // 实现一个X509TrustManager接口,用于绕过验证,不用修改里面的方法
  63. X509TrustManager trustManager = new X509TrustManager() {
  64. @Override
  65. public void checkClientTrusted(X509Certificate[] paramArrayOfX509Certificate,
  66. String paramString) throws CertificateException {
  67. }
  68. @Override
  69. public void checkServerTrusted(X509Certificate[] paramArrayOfX509Certificate,
  70. String paramString) throws CertificateException {
  71. }
  72. @Override
  73. public X509Certificate[] getAcceptedIssuers() {
  74. return null;
  75. }
  76. };
  77. sc.init(null, new TrustManager[] { trustManager }, null);
  78. return sc;
  79. }
  80. }

2、OkHttpClient

  1. package com.tencent.wemeet.gateway.restapisdk.util;
  2. import lombok.extern.slf4j.Slf4j;
  3. import okhttp3.OkHttpClient;
  4. import javax.net.ssl.*;
  5. import java.security.KeyStore;
  6. import java.security.NoSuchAlgorithmException;
  7. import java.util.Arrays;
  8. import java.util.concurrent.TimeUnit;
  9. /**
  10. * @author dongliang7
  11. * @projectName tenxun-meeting-api
  12. * @ClassName SSLSocketClient.java
  13. * @description: 创建 OkHttpClient 不进行SSL(证书)验证
  14. * @createTime 2021年11月19日 09:50:00
  15. */
  16. @Slf4j
  17. public class SSLSocketClient {
  18. public static OkHttpClient getUnsafeOkHttpClient() {
  19. try {
  20. // 创建不验证证书链的信任管理器
  21. final TrustManager[] trustAllCerts = new TrustManager[]{
  22. new X509TrustManager() {
  23. @Override
  24. public void checkClientTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
  25. @Override
  26. public void checkServerTrusted(java.security.cert.X509Certificate[] chain, String authType) {}
  27. @Override
  28. public java.security.cert.X509Certificate[] getAcceptedIssuers() {
  29. return new java.security.cert.X509Certificate[]{};
  30. }
  31. }
  32. };
  33. if (trustAllCerts.length != 1 || !(trustAllCerts[0] instanceof X509TrustManager)) {
  34. throw new IllegalStateException("Unexpected default trust managers:" + Arrays.toString(trustAllCerts));
  35. }
  36. X509TrustManager x509TrustManager = (X509TrustManager) trustAllCerts[0];
  37. // 安装全信任信任管理器
  38. final SSLContext sslContext = SSLContext.getInstance("SSL");
  39. sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
  40. // 使用我们完全信任的管理器创建 ssl 套接字工厂
  41. final SSLSocketFactory sslSocketFactory = sslContext.getSocketFactory();
  42. OkHttpClient.Builder builder = new OkHttpClient.Builder()
  43. .connectTimeout(60 , TimeUnit.SECONDS).readTimeout(60 , TimeUnit.SECONDS).writeTimeout(120 , TimeUnit.SECONDS);
  44. builder.sslSocketFactory(sslSocketFactory , x509TrustManager);
  45. builder.hostnameVerifier(new HostnameVerifier() {
  46. @Override
  47. public boolean verify(String hostname, SSLSession session) {
  48. return true;
  49. }
  50. });
  51. OkHttpClient okHttpClient = builder.build();
  52. return okHttpClient;
  53. } catch (Exception e) {
  54. log.error("创建OkHttpClient不进行SSL(证书)验证失败:{}", e.getMessage());
  55. throw new RuntimeException(e);
  56. }
  57. }
  58. }

获取OkHttpClient :

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

在minio中的运用

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

转载自:https://www.cnblogs.com/dongl961230/p/15594627.html

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/weixin_40725706/article/detail/440646
推荐阅读
相关标签
  

闽ICP备14008679号