简体   繁体   中英

Java HTTPS connection with SSL certificate Error

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.

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

This message is due to:

  1. Either the JRE does not have the root CA as a trusted entry in its keystore.
  2. The server is not sending a proper chain.

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.

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

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.

Edit:

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.

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());
}

}

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM