I try to consume a REST API via a Rest template. I add its certificate in my trust store but I have an Exception.
The cert DN is: *.domain.com and I try GET https://api.domain.com
the stack trace:
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
My service method
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());
Have you some idea why this is happening?
Sounds like X509TrustManagerImpl
has problems to accept the certificate.
This can happen when the TLS certificate is not from a trusted source (e.g. self-signed or just not accepted by java trust store).
I would try to execute your code with another (newer) JDK - e.g. Oracle or Amazon Coretto, where trust stores are maintained and up-to-date.
When it works with other, newer JDK...
If this works - TLS certificate seems to be valid. If you need to use your JDK (e.g. license issues) you could import certificate into your local trust store.
When it also not works with other, newer JDK...
If this does not work... Look at the certificate and check if it's really trustful... Maybe a security issue... e.g. man in the middle attack (or just a company proxy making odd things with certificates...)
Or ... its just a self signed certificate, e.g. used on a test server. If you are really, really sure that you can trust a self signed certificate (e.g. when its your own test server), you can either import it into your trust store, or make a TRUST_ALL approach like done in : https://github.com/Daimler/sechub/blob/develop/sechub-adapter/src/main/java/com/daimler/sechub/adapter/support/TrustAllSupport.java
But the correct way would be to just ensure certificates are trustful.