0

I am trying to try catch two cases when the url is http or https and do the respective URLConnections. However when I use the code below, the https connection always throws an IOException, while http connection works.

//proxy, url, are given variables
URL checkUrl = new URL(url);
            HttpURLConnection connect = null;
            if(checkUrl.getProtocol().toLowerCase().equals("https")) {
                connect = (HttpsURLConnection) new  URL(url).openConnection(proxy);
                
            }else {
                connect = (HttpURLConnection) new  URL(url).openConnection(proxy);
            }

....
connect.connect();

After the connect() command my program jumps to the catch IOException branch. and I get 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

When I debug it, my connect variable gets a value of "HttpsURLConnectionImpl (id=48)" after it does the httpsurlconnection openConnection() command.

punpun123
  • 11
  • 5
  • That IOException tells you what’s going wrong. Edit your question to show us the full exception class name and message. – VGR Jul 31 '20 at 03:35
  • @VGR, there is no run time exception message alert, it's only an exception i threw from writing a try catch. It jumps to the IOexception when i get to connect.connect(); – punpun123 Jul 31 '20 at 03:38
  • I don’t understand. Your title says the problem is that the connection throws an IOException, but you’re saying that you are manually throwing an IOException? Can’t you just… stop throwing the IOException? – VGR Jul 31 '20 at 03:41
  • @VGR my bad, i got 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 – punpun123 Jul 31 '20 at 03:45
  • Since you are using https connection, It is verifying the certificate you can download the cert by hitting the url in browser. – Arun Prasat Jul 31 '20 at 03:46
  • If you put that same https: URL into any browser, the browser will tell you that the certificate is not valid. Your exception is the equivalent of that. To accept invalid certificates, you will need to create an SSLContext with a custom TrustManager. See https://stackoverflow.com/questions/1201048/allowing-java-to-use-an-untrusted-certificate-for-ssl-https-connection. – VGR Jul 31 '20 at 03:49

2 Answers2

0

The error PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target always means one thing: your JVM does not trust the https endpoint you are trying to connect to. JVM's come with ~90 certificates in their trust store. If the server you connect to presents its certificate and a CA chain that is anchored by one of them, you won't see that issue. You can see exactly the certificate chain the server presents by using openssl (ex. openssl.exe s_client -connect www.google.com:443), portecle, or a tool like certcheckerapp.com (which you can run locally as a Docker image).

One hack work-around is to add the server's certificate to your truststore (use keytool -import -file <thecertificate.cer> -keystore <location-of-cacerts-file>. The ideal solution is to make sure that the server you connect to presents a chain and that you add the trust anchor (top most certificate in the chain) to your truststore.

Toby
  • 186
  • 3
0

This means you do not have proper certificates in your trust store. This store is used by Java programs in order to verify server certificates.

Normally if you did java installation correctly the default store is to contain the majority of the CAs certificates so there should not be issues in maintaining the connection to the most of https resources. However if you didn't have proper installation or you are trying to access some corporate resource that has its certificate signed with corporate CA key you might have no required certificate in your store.

The workaround is to import the certificate returned by your server directly to your trust store. Here is the detailed guide on how to do that.

Alexey R.
  • 8,057
  • 2
  • 11
  • 27