Reputation: 1191
I'm trying to use the SSL certificate obtained with StartSSL.com on an Apache server. The connection with browser is fine, but when I try to use a Java application, I got this exeption:
Exception in thread "main" 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
I don't understand what could be the problem, because with the browser, I got the SSL with green label.
Upvotes: 6
Views: 44603
Reputation: 987
I recomend use http-request built on apache http api.
import org.junit.Test;
import static org.apache.http.HttpHeaders.ACCEPT;
import static org.apache.http.HttpStatus.SC_OK;
import static org.apache.http.entity.ContentType.APPLICATION_XML;
import static org.junit.Assert.assertEquals;
public class HttpRequestSSLTest {
private final HttpRequest<?> httpRequest = HttpRequestBuilder.createGet("https://mms.nw.ru/")
.trustAllCertificates()
.trustAllHosts()
.addDefaultHeader(ACCEPT, APPLICATION_XML.getMimeType())
.build();
@Test
public final void ignoreSSLAndHostsTest() throws Exception {
assertEquals(SC_OK, httpRequest.execute().getStatusCode());
}
}
Upvotes: 0
Reputation: 3913
This message is due to:
But, 2 is not valid in your case since the browser is able to construct the chain and validate the certificate.
Consequently you need to get the root CA and put it in the JRE keystore as a trusted entry. There are lots of resources that document the "how". One of them is: https://access.redhat.com/documentation/en-US/Fuse_Message_Broker/5.3/html/Security_Guide/files/i379776.html
EDIT 1: Since you want to share the java app, it would we worth the effort to get a certificate from a CA whose root is already trusted in the trust store for the Java versions that your app supports.
Upvotes: 1
Reputation: 169
There are a few questions like this already on SO (like this one: PKIX path building failed: unable to find valid certification path to requested target).
The usual answer to this is that your java client doesn't have certificates needed to complete the certificate chain.
If you need proper certificate validation, then you'll have to figure out where the certificate chain breaks down. If you don't (because this is a proof of concept or a dev sandbox, or whatever), then you can easily work around this by adding the certificate to the trust store you use with your client.
As for why your browser accepts this, it's likely that either your browser has the certificates in the chain that you need or you've absentmindedly told your browser to trust the certificate even though it also wasn't able to validate the certificate.
Upvotes: 0
Reputation: 34
As far as I understand this is related to the Java Certificate Keystore. Your certificate is not accepted by java. Here is a link how to add your certificate to Java trusted Certificates keystore: https://docs.oracle.com/javase/tutorial/security/toolsign/rstep2.html
Upvotes: 0
Reputation: 4692
The problem is your Java is not trusting the certificate. You have to import it to your java's truststore
.
# Copy the certificate into the directory Java_home\Jre\Lib\Security
# Change your directory to Java_home\Jre\Lib\Security>
# Import the certificate to a trust store.
# Here's the import command:
keytool -import -alias ca -file somecert.cer -keystore cacerts -storepass changeit [Return]
Trust this certificate: [Yes]
changeit is default truststore password.
For every certificate that you imported into your truststore you have to provide a new alias.
The import method is a quote from Here
Upvotes: 10