[Solved] JAVA HttpClient Send Https request certificate error:PKIX path building failed:

Recently, when using httpclient to connect with the third-party SMS interface, a certificate invalidation error was reported during the local test.

1. Post request of Encapsulated HttpClient:

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) // Set the connection timeout, in milliseconds
                .setConnectionRequestTimeout(1000)
                .setSocketTimeout(5000) // timeout for requesting data, in milliseconds
                .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;
    }

However, an error will be reported when accessing some self signed HTTPS requests. This problem is caused by the invalid link certificate, because the self signed certificate will be recognized as an unsafe link.

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

2. Solutions

  1. Set the security certificate of jdk according to the online method -> No work
  2. Set maven to ignore the certificate checksum -> no work
  3. Yml file configuration httpclient ignore SSL checksum, seems to have no effect.
  4. Finally used the method of modifying the code, the principle is also to ignore the certificate checksum, but the code produced the effect, it is estimated that the construction is related to the Httpclient.

 

Modify the original code

// Ignore SSL Security Certification
**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()) {

Read More: