Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Java: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target

I have a class that will download a file from a https server. When I run it, it returns a lot of errors. It seems that I have a problem with my certificate. Is it possible to ignore the client-server authentication? If so, how?

package com.da;  import java.io.FileOutputStream; import java.io.IOException; import java.nio.CharBuffer; import java.util.concurrent.Future;  import org.apache.http.HttpResponse; import org.apache.http.client.utils.URIUtils; import org.apache.http.impl.nio.client.DefaultHttpAsyncClient; import org.apache.http.nio.IOControl; import org.apache.http.nio.client.HttpAsyncClient; import org.apache.http.nio.client.methods.AsyncCharConsumer; import org.apache.http.nio.client.methods.HttpAsyncGet; import org.apache.http.nio.client.methods.HttpAsyncPost;  public class RSDDownloadFile {     static FileOutputStream fos;      public void DownloadFile(String URI, String Request) throws Exception     {         java.net.URI uri = URIUtils.createURI("https", "176.66.3.69:6443", -1, "download.aspx",                 "Lang=EN&AuthToken=package", null);         System.out.println("URI Query: " + uri.toString());          HttpAsyncClient httpclient = new DefaultHttpAsyncClient();         httpclient.start();         try {             Future<Boolean> future = httpclient.execute(                     new HttpAsyncGet(uri),                     new ResponseCallback(), null);              Boolean result = future.get();             if (result != null && result.booleanValue()) {                 System.out.println("\nRequest successfully executed");             } else {                 System.out.println("Request failed");             }                       }          catch(Exception e){             System.out.println("[DownloadFile] Exception: " + e.getMessage());         }         finally {             System.out.println("Shutting down");             httpclient.shutdown();         }         System.out.println("Done");        }      static class ResponseCallback extends AsyncCharConsumer<Boolean> {          @Override         protected void onResponseReceived(final HttpResponse response) {              System.out.println("Response: " + response.getStatusLine());              System.out.println("Header: " + response.toString());              try {                     //if(response.getStatusLine().getStatusCode()==200)                      fos = new FileOutputStream( "Response.html" );              }catch(Exception e){                  System.out.println("[onResponseReceived] Exception: " + e.getMessage());              }         }          @Override         protected void onCharReceived(final CharBuffer buf, final IOControl ioctrl) throws IOException {             try             {                 while (buf.hasRemaining())                  {                     //System.out.print(buf.get());                     fos.write(buf.get());                 }             }catch(Exception e)             {                 System.out.println("[onCharReceived] Exception: " + e.getMessage());             }         }          @Override         protected void onCleanup() {             try             {                              if(fos!=null)                     fos.close();             }catch(Exception e){                 System.out.println("[onCleanup] Exception: " + e.getMessage());                      }              System.out.println("onCleanup()");         }          @Override         protected Boolean buildResult() {             return Boolean.TRUE;         }      } } 

Errors:

URI Query: https://176.66.3.69:6443/download.aspx?Lang=EN&AuthToken=package Aug 2, 2011 3:47:57 PM org.apache.http.impl.nio.client.NHttpClientProtocolHandler exception SEVERE: I/O error: General SSLEngine problem javax.net.ssl.SSLHandshakeException: General SSLEngine problem     at com.sun.net.ssl.internal.ssl.Handshaker.checkThrown(Unknown Source)     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.checkTaskThrown(Unknown Source)     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.writeAppRecord(Unknown Source)     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.wrap(Unknown Source)     at javax.net.ssl.SSLEngine.wrap(Unknown Source)     at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:154)     at org.apache.http.impl.nio.reactor.SSLIOSession.isAppInputReady(SSLIOSession.java:276)     at org.apache.http.impl.nio.client.InternalClientEventDispatch.inputReady(InternalClientEventDispatch.java:79)     at org.apache.http.impl.nio.reactor.BaseIOReactor.readable(BaseIOReactor.java:161)     at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvent(AbstractIOReactor.java:335)     at org.apache.http.impl.nio.reactor.AbstractIOReactor.processEvents(AbstractIOReactor.java:315)     at org.apache.http.impl.nio.reactor.AbstractIOReactor.execute(AbstractIOReactor.java:275)     at org.apache.http.impl.nio.reactor.BaseIOReactor.execute(BaseIOReactor.java:104)     at org.apache.http.impl.nio.reactor.AbstractMultiworkerIOReactor$Worker.run(AbstractMultiworkerIOReactor.java:542)     at java.lang.Thread.run(Unknown Source) Caused by: javax.net.ssl.SSLHandshakeException: General SSLEngine problem     at com.sun.net.ssl.internal.ssl.Alerts.getSSLException(Unknown Source)     at com.sun.net.ssl.internal.ssl.SSLEngineImpl.fatal(Unknown Source)     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)     at com.sun.net.ssl.internal.ssl.Handshaker.fatalSE(Unknown Source)     at com.sun.net.ssl.internal.ssl.ClientHandshaker.serverCertificate(Unknown Source)     at com.sun.net.ssl.internal.ssl.ClientHandshaker.processMessage(Unknown Source)     at com.sun.net.ssl.internal.ssl.Handshaker.processLoop(Unknown Source)     at com.sun.net.ssl.internal.ssl.Handshaker$1.run(Unknown Source)     at java.security.AccessController.doPrivileged(Native Method)     at com.sun.net.ssl.internal.ssl.Handshaker$DelegatedTask.run(Unknown Source)     at org.apache.http.impl.nio.reactor.SSLIOSession.doHandshake(SSLIOSession.java:180)     ... 9 more 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(Unknown Source)     at sun.security.validator.PKIXValidator.engineValidate(Unknown Source)     at sun.security.validator.Validator.validate(Unknown Source)     at com.sun.net.ssl.internal.ssl.X509TrustManagerImpl.checkServerTrusted(Unknown Source)     at com.sun.net.ssl.internal.ssl.JsseX509TrustManager.checkServerTrusted(Unknown Source)     ... 16 more Caused by: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target     at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(Unknown Source)     at java.security.cert.CertPathBuilder.build(Unknown Source)     ... 21 more onCleanup()  [DownloadFile] Exception: javax.net.ssl.SSLHandshakeException: General SSLEngine problem Shutting down Done 
like image 540
neztreh Avatar asked Aug 02 '11 08:08

neztreh


People also ask

What does Cannot find valid certification path to requested target mean?

This issue might arise if you are using a self-signed certificate or a certificate that's been issued by an internal certificate authority, or if your clients (e.g., browser, Java) are outdated. Trust is handled by having the root and intermediate certificates of your SSL certificate on a trusted keystore.

What is Sun Security Validator ValidatorException?

If Server returns a certificate that cannot be validated against the certificates a browser or Java client holds in its truststore then it throws the "sun. security. validator. ValidatorException: PKIX path building failed: sun.

What is Pkix path building?

What does the PKIX path building error mean? PKIX stands for Public Key Infrastructure X509. Whenever Java attempts to connect to another application over SSL, the connection will only succeed if it can trust the application.


2 Answers

The problem appears when your server has self signed certificate. To workaround it you can add this certificate to the list of trusted certificates of your JVM.

In this article author describes how to fetch the certificate from your browser and add it to cacerts file of your JVM. You can either edit JAVA_HOME/jre/lib/security/cacerts file or run you application with -Djavax.net.ssl.trustStore parameter. Verify which JDK/JRE you are using too as this is often a source of confusion.

See also: How are SSL certificate server names resolved/Can I add alternative names using keytool? If you run into java.security.cert.CertificateException: No name matching localhost found exception.

like image 152
Maxim Mazin Avatar answered Sep 19 '22 06:09

Maxim Mazin


Here's what reliably works for me on macOS. Make sure to replace example.com and 443 with the actual hostname and port you're trying to connect to, and give a custom alias. The first command downloads the provided certificate from the remote server and saves it locally in x509 format. The second command loads the saved certificate into Java's SSL trust store.

openssl x509 -in <(openssl s_client -connect example.com:443 -prexit 2>/dev/null) -out ~/example.crt sudo keytool -importcert -file ~/example.crt -alias example -keystore $(/usr/libexec/java_home)/jre/lib/security/cacerts -storepass changeit 
like image 23
Gabe Martin-Dempesy Avatar answered Sep 18 '22 06:09

Gabe Martin-Dempesy