首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >问答首页 >sun.security.provider.certpath.SunCertPathBuilderException::SSLHandshakeException: ValidatorException: PKIX路径构建失败

sun.security.provider.certpath.SunCertPathBuilderException::SSLHandshakeException: ValidatorException: PKIX路径构建失败
EN

Stack Overflow用户
提问于 2016-06-19 10:50:57
回答 2查看 4.5K关注 0票数 1

我尝试使用没有证书检查的https请求本地服务。但我有这个要求。

代码语言:javascript
复制
javax.net.ssl.SSLHandshakeException: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

下面是代码的一部分:

代码语言:javascript
复制
try {
            RestTemplate restTemplate = new RestTemplate();
            HttpsURLConnection.setDefaultHostnameVerifier(
                    (hostname, session) -> hostname.equals("IPADDRESS"));
            responseEntity = restTemplate.exchange(url, HttpMethod.POST, httpEntity, String.class);
        } catch (HttpClientErrorException e) {
            LOGGER.error(e.toString());
        }

这里怎么了?

EN

回答 2

Stack Overflow用户

回答已采纳

发布于 2016-06-21 14:32:41

喂,

我用下面的代码部分解决了这个问题:

代码语言:javascript
复制
private void disableCertificateVerification() {
        TrustManager[] trustAllCerts = new TrustManager[] { new X509TrustManager() {
            public java.security.cert.X509Certificate[] getAcceptedIssuers() {
                return null;
            }

            @Override
            public void checkClientTrusted(java.security.cert.X509Certificate[] arg0, String arg1)                  throws CertificateException {
            }

            @Override
            public void checkServerTrusted(java.security.cert.X509Certificate[] arg0, String arg1)
                    throws CertificateException {
            }
        } };

        try {
            SSLContext sslContext = SSLContext.getInstance("SSL");
            sslContext.init(null, trustAllCerts, new java.security.SecureRandom());
            HttpsURLConnection.setDefaultSSLSocketFactory(sslContext.getSocketFactory());
HttpsURLConnection.setDefaultHostnameVerifier(allHostsValid);
            HttpsURLConnection.setDefaultHostnameVerifier(
                    (hostname, session) -> hostname.equals("IPADDRESS"));
        } catch (NoSuchAlgorithmException | KeyManagementException e) {
            LOGGER.error(e.toString());
        }
    }

在创建RestTemplate之前,我调用了这个函数。

票数 1
EN

Stack Overflow用户

发布于 2016-06-19 15:31:24

此问题是由于服务器证书的信任路径不完整造成的:服务器证书可能不受客户端信任。

通常的修复方法是将服务器证书导入客户端信任存储。默认的trustStore在jre/lib/security/cacerts中,但是使用自己的keystore是一个更好的实践。

您可以在使用静态方法连接或应用于所有连接之前创建一个SSLSocketFactory并添加到您的连接中。

代码语言:javascript
复制
 HttpsURLConnection.setDefaultSSLSocketFactory(sslFactory);

这是一个创建套接字工厂的示例。

代码语言:javascript
复制
/* Load the keyStore that includes the server cert as a "trusted" entry. */
KeyStore keyStore = ... 
TrustManagerFactory tmf = 
  TrustManagerFactory.getInstance(TrustManagerFactory.getDefaultAlgorithm());
tmf.init(keyStore);
SSLContext ctx = SSLContext.getInstance("TLS");
ctx.init(null, tmf.getTrustManagers(), null);
sslFactory = ctx.getSocketFactory();

加载keyStore的示例

代码语言:javascript
复制
KeyStore keyStore = KeyStore.getInstance(KeyStore.getDefaultType());
keyStore.load(trustStore, trustStorePassword);
trustStore.close();

还可以使用系统属性配置信任存储。

代码语言:javascript
复制
 System.setProperty("javax.net.ssl.trustStore", "pathtoyourjavakeystorefile");
 System.setProperty("javax.net.ssl.trustStorePassword", "password");

创建密钥存储文件的最简单方法是使用GUI工具Portecle。新KeyStore >导入受信任证书

如果要从root“信任”所有证书,或只导入服务器证书,则可以导入链的根证书。对于自签名证书,直接导入它。

票数 1
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/37906420

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档