为什么我在尝试通过 REST API 使用数据时收到 SunCertPathBuilderException?
Why am I getting a SunCertPathBuilderException when trying to consume data via REST API?
我尝试通过 Rest 模板使用 REST API。
我在我的信任库中添加了它的证书,但出现异常。
证书 DN 是:*.domain.com 我尝试 GET https://api.domain.com
堆栈跟踪:
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1284)
... 56 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 62 more
我的服务方式
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "application/json");
headers.add("Content-Type", "application/json");
headers.add("authorization", "Bearer " + token);
HttpEntity request = new HttpEntity(headers);
ResponseEntity<String> response = restTemplate.exchange(
https://api.domain.com,
HttpMethod.GET,
request,
String.class,
1
);
System.out.println(response.getStatusCode());
你知道为什么会这样吗?
听起来 X509TrustManagerImpl
在接受证书时遇到问题。
当 TLS 证书不是来自受信任的来源(例如自签名或只是不被 java 信任库接受)时,可能会发生这种情况。
我会尝试用另一个(较新的)JDK 来执行您的代码 - 例如Oracle 或 Amazon Coretto,其中信任库得到维护并保持最新。
与其他更新版本一起使用时 JDK...
如果可行 - TLS 证书似乎有效。如果您需要使用您的 JDK(例如许可证问题),您可以将证书导入本地信任库。
当它也不适用于其他更新的 JDK...
如果这不起作用...查看证书并检查它是否真的可信...可能是安全问题...例如中间人攻击(或者只是公司代理人用证书做奇怪的事情......)
或者...它只是一个自签名证书,例如在测试服务器上使用。
如果您真的非常确定可以信任自签名证书(例如,当它是您自己的测试服务器时),您可以将其导入您的信任库,或者创建一个TRUST_ALL 方法类似于:https://github.com/Daimler/sechub/blob/develop/sechub-adapter/src/main/java/com/daimler/sechub/adapter/support/TrustAllSupport.java
但正确的方法是确保证书是可信的。
我尝试通过 Rest 模板使用 REST API。 我在我的信任库中添加了它的证书,但出现异常。
证书 DN 是:*.domain.com 我尝试 GET https://api.domain.com
堆栈跟踪:
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:323)
at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java:217)
at sun.security.validator.Validator.validate(Validator.java:218)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java:126)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:209)
at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java:249)
at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java:1284)
... 56 more
Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java:174)
at java.security.cert.CertPathBuilder.build(CertPathBuilder.java:238)
at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java:318)
... 62 more
我的服务方式
HttpHeaders headers = new HttpHeaders();
headers.add("Accept", "application/json");
headers.add("Content-Type", "application/json");
headers.add("authorization", "Bearer " + token);
HttpEntity request = new HttpEntity(headers);
ResponseEntity<String> response = restTemplate.exchange(
https://api.domain.com,
HttpMethod.GET,
request,
String.class,
1
);
System.out.println(response.getStatusCode());
你知道为什么会这样吗?
听起来 X509TrustManagerImpl
在接受证书时遇到问题。
当 TLS 证书不是来自受信任的来源(例如自签名或只是不被 java 信任库接受)时,可能会发生这种情况。
我会尝试用另一个(较新的)JDK 来执行您的代码 - 例如Oracle 或 Amazon Coretto,其中信任库得到维护并保持最新。
与其他更新版本一起使用时 JDK...
如果可行 - TLS 证书似乎有效。如果您需要使用您的 JDK(例如许可证问题),您可以将证书导入本地信任库。
当它也不适用于其他更新的 JDK...
如果这不起作用...查看证书并检查它是否真的可信...可能是安全问题...例如中间人攻击(或者只是公司代理人用证书做奇怪的事情......)
或者...它只是一个自签名证书,例如在测试服务器上使用。 如果您真的非常确定可以信任自签名证书(例如,当它是您自己的测试服务器时),您可以将其导入您的信任库,或者创建一个TRUST_ALL 方法类似于:https://github.com/Daimler/sechub/blob/develop/sechub-adapter/src/main/java/com/daimler/sechub/adapter/support/TrustAllSupport.java
但正确的方法是确保证书是可信的。