Java使用HttpClient发送Https请求证书失效:PKIX path building failed:

最近使用HttpClient对接第三方短信接口,在进行本地测试时报了一个证书失效的错误。

1. 封装的HttpClient的Post请求
public static Map<String, Object> postReq(String URL, Map<String, Object> paramMap, Map<String, String> headers) throws Exception {
        Map<String, Object> map = new HashMap<String, Object>();

        RequestConfig requestConfig = RequestConfig.custom()
                .setConnectTimeout(2000) // 设置连接超时时间,单位毫秒
                .setConnectionRequestTimeout(1000)
                .setSocketTimeout(5000) // 请求获取数据的超时时间,单位毫秒
                .build();
        HttpRequestRetryHandler myRetryHandler = new HttpRequestRetryHandler() {
            @Override
            public boolean retryRequest(IOException exception, int executionCount, HttpContext context) {
                return false;
            }
        };

        try (CloseableHttpClient client = HttpClients.custom()
                .setDefaultRequestConfig(requestConfig)
                .setRetryHandler(myRetryHandler)
                .build()) {

            HttpPost httpPost = new HttpPost(URL);
            if (paramMap != null) {
                JSONObject paramJson = new JSONObject(paramMap);
                StringEntity paramEntity = new StringEntity(paramJson.toString(), "UTF-8");
                paramEntity.setContentType("application/json; charset=utf-8");
                httpPost.setEntity(paramEntity);
            }
            httpPost.setConfig(requestConfig);

            if (headers != null && !headers.isEmpty()) {
                for (String key : headers.keySet()) {
                    String value = headers.get(key);
                    httpPost.setHeader(key, value);
                }
            }

            CloseableHttpResponse response = client.execute(httpPost);

            HttpEntity entity = response.getEntity();

            if (entity != null) {
                String responseStr = EntityUtils.toString(entity, "UTF-8");
                if (responseStr.isEmpty()) {
                    responseStr = "{}";
                }

                int statusCode = response.getStatusLine().getStatusCode();
                if (HttpServletResponse.SC_OK == statusCode) {
                    try {
                        JSONObject dataJson = (JSONObject) JSONObject.parse(responseStr);
                        map = new HashMap<>(dataJson);
                    } catch (Exception e) {
                        map.put("reponse", responseStr);
                    }
                } else {
                    return map;
                }
            }
            response.close();
        }
        return map;
    }

但是在访问一些自签的https请求时会报错,该问题是链接证书无效导致,原因是由于自签证书会被识别为不安全链接。

sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
2. 解决方法

我试着将请求链接的证书文件添加到jdk的cer证书信任库中,但是没有产生效果。(短信接口的证书无效)报了另外一个异常:
javax.net.ssl.SSLPeerUnverifiedException: Certificate for doesn’t match any of the subject alternative names: []

查看了一些解决方法,也是比较多使用信任链接证书的方式忽略SSL的校验
https://stackoverflow.com/questions/39762760/javax-net-ssl-sslexception-certificate-doesnt-match-any-of-the-subject-alterna

查看了Apache HttpClient官方的回答
(https://issues.apache.org/jira/browse/HTTPCLIENT-2047)
应该是HttpClient本身的问题,4.5.10和4.5.11版本 DefaultHostnameVerifier 中的回归导致拒绝具有非标准域的证书。
需要信任证书来解决,问题在4.5.12解决,但是我升级了HttpClient的版本也没有效果(原版本4.5.10)

  1. 根据网上方法设置了jdk的安全证书-> 没有解决
  2. 设置了maven忽略证书校验->没有解决
  3. 升级HttpClient版本-> 没有解决
  4. yml文件配置httpclient忽略SSL校验,貌似也没有效果。
  5. 最后使用了修改代码的方法,原理也是忽略证书校验,但是代码产生了效果,估计是和构建的Httpclient有关

修改原代码

// 忽略SSL安全认证
**SSLConnectionSocketFactory scsf = new SSLConnectionSocketFactory(
        SSLContexts.custom().loadTrustMaterial(null, new TrustSelfSignedStrategy()).build(),
        NoopHostnameVerifier.INSTANCE);**

try (CloseableHttpClient client = **HttpClients.custom().setSSLSocketFactory(scsf)**
        .setDefaultRequestConfig(requestConfig)
        .setRetryHandler(myRetryHandler)
        .build()) {
  • 0
    点赞
  • 4
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值