当前位置: 首页 > article >正文

Java代码调用https(SSL证书验证问题)

Java代码调用https接口SSL证书验证问题

现有一个https接口,如下

@Test
public void test1() {
    String url = "https://iservericloudhx.yndk.cn:32613/iserver/services/map-mongodb-C_YGYX_530000_2022/wms111/C_YGYX_530000_2022";
    RestTemplate restTemplate = new RestTemplate();
    String response = restTemplate.getForObject(url, String.class);
    log.info("-----map get ----- reponse {}", response);
}

直接执行代码,会报如下错误

threw exception [Request processing failed; nested exception is org.springframework.web.client.ResourceAccessException: I/O error on GET request for "https://iservericloudhx.yndk.cn:32613/iserver/services/map-mongodb-C_YGYX_530000_2022/wms111/C_YGYX_530000_2022": PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target; nested exception is javax.net.ssl.SSLHandshakeException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target] with root cause

sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
	at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java:141) ~[na:1.8.0_261]
	at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:126) ~[na:1.8.0_261]
	at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:280) ~[na:1.8.0_261]
	at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:434) ~[na:1.8.0_261]
	at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:306) ~[na:1.8.0_261]
	at sun.security.validator.Validator.validate(Validator.java:271) ~[na:1.8.0_261]

这是因为Java在访问SSL加密的网站时,需要从JDK的KeyStore(存储位置为%JAVA_HOME%\jre\lib\security\cacerts)里面查找相对应的证书,如果不能找到就会报以上错误!

如何解决这个问题呢?

方式1:绕过SSL证书验证。

// 如果使用的是 apache 的http工具
String url = "https://xxx";
HttpClient httpClient = SkipHttpsUtil.wrapClient();
HttpGet httpGet = new HttpGet(url);
try {
    HttpResponse response = httpClient.execute(httpGet);
    HttpEntity entity = response.getEntity();
    if (ObjectUtil.isNull(entity)) {
        return null;
    }
    String res = EntityUtils.toString(entity, "utf-8");
    return JSON.parseObject(res);
} catch (Exception ex) {
    ex.printStackTrace();
    log.error("execute error ---> ", ex);
}

// 如果使用的 RestTemplate
// 重写SimpleClientHttpRequestFactory类
/**
 * @description:
 * @author: laizhenghua
 * @date: 2022/8/24 11:16
 */
public class RequestFactory extends SimpleClientHttpRequestFactory {
    @Override
    protected void prepareConnection(HttpURLConnection connection, String httpMethod) throws IOException {
        if (connection instanceof HttpsURLConnection) {
            prepareHttpsConnection((HttpsURLConnection) connection);
        }
        super.prepareConnection(connection, httpMethod);
    }

    private void prepareHttpsConnection(HttpsURLConnection connection) {
        connection.setHostnameVerifier(new SkipHostnameVerifier());
        try {
            connection.setSSLSocketFactory(createSslSocketFactory());
        } catch (Exception ex) {
            // Ignore
        }
    }

    private SSLSocketFactory createSslSocketFactory() throws Exception {
        javax.net.ssl.SSLContext context = javax.net.ssl.SSLContext.getInstance("TLS");
        context.init(null, new TrustManager[] { new SkipX509TrustManager() }, new SecureRandom());
        return context.getSocketFactory();
    }

    private class SkipHostnameVerifier implements HostnameVerifier {
        @Override
        public boolean verify(String s, SSLSession sslSession) {
            return true;
        }
    }

    private static class SkipX509TrustManager implements X509TrustManager {
        @Override
        public X509Certificate[] getAcceptedIssuers() {
            return new X509Certificate[0];
        }

        @Override
        public void checkClientTrusted(X509Certificate[] chain, String authType) {

        }

        @Override
        public void checkServerTrusted(X509Certificate[] chain, String authType) {

        }
    }
}

// 重新封装RestTemplate实例
/**
 * @description:
 * @author: laizhenghua
 * @date: 2022/7/29 17:04
 */
@Configuration
public class RestTemplateConfiguration {
    @Bean
    public RestTemplate restTemplate() {
        RequestFactory factory = new RequestFactory(); // 这里RequestFactory就是上述重写的
        factory.setReadTimeout(30000);
        factory.setConnectTimeout(30000);
        return new RestTemplate(factory);
    }
}

方式2:将所访问的SSL站点证书从浏览器导出,并通过keytool命令导入到JDK的证书库中。

1、先从浏览器导出SSL证书(详见下图)
在这里插入图片描述
在这里插入图片描述
会得到一个证书文件!

2、将证书文件导入到JDK的证书库中,详见以下命令

# 注意点1: keytool 命令如果使用不了,就从Java安装bin目录cmd进行操作,如 cmd E:\jdk1.8\bin
# 注意点2:执行 keytool 命令会提示"输入密钥库口令:" 口令是changeit 如下
# C:\Users\赖正华>keytool -list -alias _.yndk.cn -v -keystore "%JAVA_HOME%\jre\lib\security\cacerts"
# 输入密钥库口令: changeit

# 导入
keytool -import -alias _.yndk.cn -keystore "%JAVA_HOME%\jre\lib\security\cacerts" -file E:\_.yndk.cn.crt
# -alias 指定证书别名一般设置域名即可
# -keystore 指定证书导入位置
# -file 指定证书文件(就是浏览器导出的证书文件)

# 删除
keytool -delete -alias _.yndk.cn -keystore "%JAVA_HOME%\jre\lib\security\cacerts"

# 查看
keytool -list -alias _.yndk.cn -v -keystore "%JAVA_HOME%\jre\lib\security\cacerts"

导入证书后我们再来访问https接口,就不报错了。


http://www.kler.cn/a/316744.html

相关文章:

  • StructuredStreaming (一)
  • 陪诊问诊APP开发实战:基于互联网医院系统源码的搭建详解
  • React的基础API介绍(二)
  • INQUIRE:一个包含五百万张自然世界图像,涵盖10,000个不同物种的专为专家级文本到图像检索任务设计的新型基准数据集。
  • 【STM32F1】——无线收发模块RF200与串口通信
  • [ 网络安全介绍 5 ] 为什么要学习网络安全?
  • 828华为云征文 | 将Vue项目部署到Flexus云服务器X实例并实现公网访问
  • 使用Conda配置python环境到Pycharm------Window小白版
  • SVN泄露 CTFHUB 解题笔记
  • 论文不会写快来看!分享4款ai改写论文软件
  • uni-app快速入门
  • 异常值理解
  • 尚品汇-秒杀商品定时任务存入缓存、Redis发布订阅实现状态位(五十一)
  • 修复 blender 中文输入 BUG (linux/wayland/GNOME/ibus)
  • 如何降低H5商城系统的开发成本
  • unixODBC编程(一)安装配置ODBC
  • 【STL】vector 基础,应用与操作
  • Java综合练习题—TCP通信协议+xml操作+序列化反序列化综合题
  • 如何使用ant design vue的a-select下拉框,实现既能输入内容,也可以下拉选择的效果,apiselect同样适用
  • 浅谈spring 后端项目配置logback日志
  • 无人机之4G模块的主要功能和优势
  • 华为HarmonyOS地图服务 1 -- 如何实现地图呈现?
  • Flask高级特性实战
  • 字符串反转
  • 【kafka-04】kafka线上问题以及高效原理
  • HarmonyOS鸿蒙开发实战(5.0)网格元素拖动交换案例实践