I have some java code in Liferay 6.2 ee sp14 that needs to load a keystore JKS file in order to access some web services (using third-party libraries). If I attempt to call the code (and therefore load the JKS file) as soon as the server has loaded after a restart, it sometimes works. But sometimes it won't work, throwing an error message that suggests the JKS file wasn't actually loaded properly. And it is almost guaranteed to fail if I don't try to access the web services as soon as the server is running.
If it works the first time then it will continue to work until the server is restarted. If it doesn't work the first time then it will never work, and the only chance of getting it to work is to restart the server and try to run the code as soon as the server has loaded.
This is the error message that I see:
com.sun.xml.internal.ws.client.ClientTransportException: HTTP transport error: 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 get the same error message if I don't try to load a keystore file, or I deliberately load the wrong keystore file first, which is why I think the issue is with the keystore file not being loaded. I'm sure it's FINDING my file because I can always read it and display the contents. My theory is that some other module (probably an outdated one) is loading a different keystore file, and the system simply won't load a second file.
Is there any way to figure out what could be interfering with my keystore file being loaded, or to force it to load even if another keystore file has already been loaded?
The specific code I'm using to load the jks file:
System.setProperty("javax.net.ssl.keyStore", jksPath);
System.setProperty("javax.net.ssl.keyStorePassword", jksPass);
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("javax.net.ssl.trustStore", jksPath);
System.setProperty("javax.net.ssl.trustStorePassword", jksPass);
System.setProperty("javax.net.ssl.trustStoreType", "JKS");
I have tried clearing the properties first, but it makes no difference:
System.clearProperty("javax.net.ssl.keyStore");
System.clearProperty("javax.net.ssl.keyStorePassword");
System.clearProperty("javax.net.ssl.keyStoreType");
System.clearProperty("javax.net.ssl.trustStore");
System.clearProperty("javax.net.ssl.trustStorePassword");
System.clearProperty("javax.net.ssl.trustStoreType");
Does anyone have any suggestions? I'm really desperate here.
Related
This may look like a duplicate but it is not.
I added the certificate from the ssl endpoint to my cacerts file. I verified its added. I restarted the jvm and my computer, but I still get unable to find valid certification path to requested target exception.
In addition to adding the certificate from the ssl endpoint the following helped me fix the issue. I added this system property in my code and it helped me navigate to the required secured endpoint.
System.setProperty("javax.net.ssl.trustStore", "path/to/cacerts");
However the above one works for local, while doing it for prod deployment I moved the cacerts to my project and change the path to cacerts to the one in my project. This way it worked for both remote and local end points.
I am able to access the URL I want through a curl command from my Glassfish machine by specifying a cert.pem file.
In my Java application however, I tried using a jks file that holds the exact same information I get an exception.
I am doing this in Java:
System.setProperty("javax.net.ssl.keyStore", keystore_path);
System.setProperty("javax.net.ssl.keyStorePassword", "pass123");
Keystore path is retrieved by
getClass().getClassLoader().getResource("/keystore.jks").getPath()
While I can look inside the jks file just fine with the keytool utility, I am getting the following stacktrace from Glassfish:
sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target at sun.security.provider.certpath.SunCertPathBuilder.build(SunCertPathBuilder.java: 141) at sun.security.provider.certpath.SunCertPathBuilder.engineBuild(SunCertPathBuilder.java: 126) at java.security.cert.CertPathBuilder.build(CertPathBuilder.java: 280) at sun.security.validator.PKIXValidator.doBuild(PKIXValidator.java: 382) at sun.security.validator.PKIXValidator.engineValidate(PKIXValidator.java: 292) at sun.security.validator.Validator.validate(Validator.java: 260) at sun.security.ssl.X509TrustManagerImpl.validate(X509TrustManagerImpl.java: 324) at sun.security.ssl.X509TrustManagerImpl.checkTrusted(X509TrustManagerImpl.java: 229) at sun.security.ssl.X509TrustManagerImpl.checkServerTrusted(X509TrustManagerImpl.java: 124) at sun.security.ssl.ClientHandshaker.serverCertificate(ClientHandshaker.java: 1491) at sun.security.ssl.ClientHandshaker.processMessage(ClientHandshaker.java: 216) at sun.security.ssl.Handshaker.processLoop(Handshaker.java: 979) at sun.security.ssl.Handshaker.process_record(Handshaker.java: 914) at sun.security.ssl.SSLSocketImpl.readRecord(SSLSocketImpl.java: 1062) at sun.security.ssl.SSLSocketImpl.performInitialHandshake(SSLSocketImpl.java: 1375) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java: 1403) at sun.security.ssl.SSLSocketImpl.startHandshake(SSLSocketImpl.java: 1387) at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java: 543) at org.apache.http.conn.ssl.SSLSocketFactory.connectSocket(SSLSocketFactory.java: 409) at org.apache.http.impl.conn.DefaultClientConnectionOperator.openConnection(DefaultClientConnectionOperator.java: 177)
One of the suggestions is to specify to do a one-way handshake, but I'm not sure how to specify that.
Also, can I specify the .pem file as I do in the case of the working curl command and would that have any gain?
You need to set the trustStore variable, not the keyStore
System.setProperty("javax.net.ssl.trustStore", keystore_path);
System.setProperty("javax.net.ssl.trustStorePassword", "pass123");
Ensure also that keystore_path points to an absolute location. It can not load files from classpath
I have a simple java application which is running in my local machine which connects to some URLs. When I connect to https urls I get the Error "Unable to find certification path ..". Following the steps mentioned in other websites I exported the certificate from my browser saved it and then imported it into my cacerts keystore using the keytool command.
This worked initially for some remote website URLs. But when the URL began with "https:localhost:8083" I am still getting the same exception! Even though I followed all the steps.
Any help?
I am facing the following SSL connection exception when trying to connect to remote server:
java.net.SocketException: Default SSL context init failed: null
Most of the thread suggest that there is some problem with the keystore location that contains the certificate file.
Others like this post: Default SSL context init failed: null suggests is to create the SSL Context by yourself. But, again the issue is not resolved yet.
And here is what I did so far:
I tried to add certificate to the following file locations and all of them gave me the same error mentioned earlier:
• Cacerts file in Java Home.
• Default cacerts location for the IDE I am using (JDveloper 10.1.3.2) which is in my case : C:\JDeveloper\WorkSpace_10g\jdevstudio10132\jdk\jre\lib\security\cacerts
• New keystore that only contains this certificate.
The certificated is added using Portecle applet( I also tried keytool options from Command prompts)
I am also referring to the trustStore and keyStore in the code as follow:
System.setProperty("javax.net.ssl.trustStore", trustStore file path goes here);
System.setProperty("javax.net.ssl.trustStorePassword", password goes here);
System.setProperty("javax.net.ssl.keyStore", keyStore file path goes here);
System.setProperty("javax.net.ssl.keyStorePassword", password goes here);
In the above code the file path refer for the cacerts files mentioned earlier (Java home, default JDeveloper cacerts and newly created keystore) of course I tried each one separately.
The keystore isn't found. Check that you can open that file from within the same piece of code by the same name you're using in javax.net.ssl.keyStore.
If you're using the default cacerts you don't need to set javax.net.ssl.trustStore/trustStorePassword at all.
We have signed a JAR file using a certificate generated by MS Active Directory Certificate Services. However, when accessing it via Java Web Start we are getting the prompt that the digital signature cannot be verified even though we've installed the root CA into the certificate store on the client machine.
Now trying to look at the root CA on the client machine, using "keytool -list", I'm seeing an exception (invalid URI:file://\my_msadcs_server\path\to\CRL.crl). So now I'm not sure exactly what is going wrong.
Anyone have a suggestion or sample Java code on how I can test the downloaded JAR file's signature on the client machine in an attempt to figure out exactly why JWS is complaining? It could be that the root CA certificate has a problem (and I will chase down that avenue when my AD admin gets in) but I'd like to rule out other possibilities first. Currently the only thing I have to go on is the exception from "keytool -list", but keytool had no issues importing the root CA certificate in the first place.
Thanks in advance!,
mG.
I use jarsigner with the -verify, -verbose and -certs options. You may have to specify your -keystore, too.
I think the invalid URI message is a clue. Java file URI takes the following form: file://host/path