SocketException Default SSL context is null while connecting to remote server - java

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.

Related

Why is liferay loading my JKS file inconsistently?

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.

GET from Glassfish with specifying .pem file

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

Error in configuration of Keystore , TrustStore in java

I want to access ssl webservice.
I have generated the client bindings in Netbeans
Generated JKS and imported client pfx file to the client.jks
with ckeystorepwd and calias
Webservice Producer has shared server.jks with srvalias and srvkeystorepwd
I have configured the Keystore and TrustStore in NetBeans IDE and I am
running Main.java and
I am able to consume the webservice. I want to consume the webservice without NetBeansIDE. I need to configure the Keystroe and Truststore (client.jks,server.jks) to the
environment pragmatically.
I have included the below code in my Main.java but it is giving below error , Please guide me how can I configure the keystroe ,truststore.
Main.java Code
System.setProperty("-Djavax.net.ssl.keyStore",JKSFILE);
System.setProperty("-Djavax.net.ssl.keyStorePassword",JKSPWD);
System.setProperty("javax.net.ssl.keyStoreType", "JKS");
System.setProperty("-Djavax.net.ssl.trustStore",JKSFILET);
System.setProperty("-Djavax.net.ssl.trustStorePassword",JKSPWDT);
System.setProperty("javax.net.ssl.requireClientAuth", "true");
System.setProperty("com.sun.xml.ws.transport.http.client.
HttpTransportPipe.dump","true");
URL u;
u = new URL(MAIN_URL);
IWebService service = new
WebService(u).getWS2007HttpBindingIWebService();
Error
SEVERE: WSS1906: Invalid key provided for encryption/decryption.
java.security.InvalidKeyException: Illegal key size or default parameters
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.a(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at javax.crypto.Cipher.init(DashoA13*..)
at com.sun.xml.ws.security.opt.impl.enc.CryptoProcessor.initCipher(CryptoProcessor.java:125)
at com.sun.xml.ws.security.opt.impl.enc.CryptoProcessor.encryptData(CryptoProcessor.java:269)
at com.sun.xml.ws.security.opt.impl.enc.CryptoProcessor.encrypt(CryptoProcessor.java:153)
at com.sun.xml.ws.security.opt.impl.util.CVDataHandler.writeTo(CVDataHandler.java:69)
at javax.activation.ObjectDataContentHandler.writeTo(Unknown Source)
at javax.activation.DataHandler$1.run(Unknown Source)
at java.lang.Thread.run(Unknown Source)
Exception in thread "DataHandler.getInputStream" com.sun.xml.wss.impl.XWSSecurityRuntimeException: Unable to calculate cipher value as invalid key was provided
Resolved the issue,
I was not using the same JVM where I have copied the policy jar as
part of JCE-6 configuration in Eclipse environment.
Now I have changed the JRE for the project and able to run the program without any issue.
C:\Program Files (x86)\Java\jdk1.6.0_33\bin\java -jar "WSClient.jar"
You may have to install the unlimited strength encryption policy files: http://www.oracle.com/technetwork/java/javase/downloads/jce-6-download-429243.html
Java doesn't ship with strong encryption due to US export laws against encryption, but you can enable it separately by replacing the local_policy.jar and US_export_policy.jar from the download above in $JAVA_HOME/lib/security.

Java Application using Https Connection:"Connection refused error"

I have created a jar for my JavaAppliaction.From this application I am connecting to servlet (I am passing name and password from swing to servlet) in the WebApplicaton(here I am just displaying name and password in the servlet).
I am passing data over SSL connection(Https). It is working fine in my system.But when I tried to run jar in another system I am getting “Connection refused error”.
Note:Running jar in another system which passes data over http connection is working fine.
I have gone through this link which suggested me to create a “jssecacerts” file and paste it in $JAVA_HOME/jre/lib/security folder of the “another system”. But I am still getting same error. Why is this not working??
One possible solution: Try importing the public certificate into java default keystore using.
keytool -importcert -trustcacerts -file "path-to-public-cert" -keystore JAVA_HOME/jre/lib/security/cacerts
it will ask for keystore password default keystore password is "changeit"
You can obtain the public cert by opening your URL in a web browser (e.g chrome) click on the icon at the start of URL -> click certificate information -> details tab -> click export
button.
A better approach will be:
create a keystore using "keytool" available in JAVA_HOME/bin
Import your server's public cert in this keystore.
bundle the keystore with your app.
make a bat / sh file to run your jar providing a parameter to java command -Djavax.net.ssl.trustStore=/path-to-your-keystore
So every time your app will start it will use this custom keystore. so you don't have to copy jssecacerts file on each system your run your app on.

SSL and cert keystore

How does my Java program know where my keystore containing the certificate is?
Or alternatively: How do I tell my Java program where to look for the keystore?
After specifying the keystore in some way, how to specify the certificate to use for authenticating the server to client?
SSL properties are set at the JVM level via system properties. Meaning you can either set them when you run the program (java -D....) Or you can set them in code by doing System.setProperty.
The specific keys you have to set are below:
javax.net.ssl.keyStore- Location of
the Java keystore file containing an
application process's own certificate
and private key. On Windows, the
specified pathname must use forward
slashes, /, in place of backslashes.
javax.net.ssl.keyStorePassword - Password
to access the private key from the
keystore file specified by
javax.net.ssl.keyStore. This password
is used twice: To unlock the keystore
file (store password), and To decrypt
the private key stored in the keystore
(key password).
javax.net.ssl.trustStore - Location of
the Java keystore file containing the
collection of CA certificates trusted
by this application process (trust
store). On Windows, the specified
pathname must use forward slashes, /,
in place of backslashes, \.
If a trust store location is not
specified using this property, the
SunJSSE implementation searches for
and uses a keystore file in the
following locations (in order):
$JAVA_HOME/lib/security/jssecacerts
$JAVA_HOME/lib/security/cacerts
javax.net.ssl.trustStorePassword -
Password to unlock the keystore file
(store password) specified by
javax.net.ssl.trustStore.
javax.net.ssl.trustStoreType - (Optional)
For Java keystore file format, this
property has the value jks (or JKS).
You do not normally specify this
property, because its default value is
already jks.
javax.net.debug - To switch
on logging for the SSL/TLS layer, set
this property to ssl.
System.setProperty("javax.net.ssl.trustStore", path_to_your_jks_file);
Just a word of caution. If you are trying to open an existing JKS keystore in Java 9 onwards, you need to make sure you mention the following properties too with value as "JKS":
javax.net.ssl.keyStoreType
javax.net.ssl.trustStoreType
The reason being that the default keystore type as prescribed in java.security file has been changed to pkcs12 from jks from Java 9 onwards.
you can also mention the path at runtime using -D properties as below
-Djavax.net.ssl.trustStore=/home/user/SSL/my-cacerts
-Djavax.net.ssl.keyStore=/home/user/SSL/server_keystore.jks
In my apache spark application, I used to provide the path of certs and keystore using --conf option and extraJavaoptions in spark-submit as below
--conf 'spark.driver.extraJavaOptions=
-Djavax.net.ssl.trustStore=/home/user/SSL/my-cacerts
-Djavax.net.ssl.keyStore=/home/user/SSL/server_keystore.jks'
First of all, there're two kinds of keystores.
Individual and General
The application will use the one indicated in the startup or the default of the system.
It will be a different folder if JRE or JDK is running, or if you check the personal or the "global" one.
They are encrypted too
In short, the path will be like:
$JAVA_HOME/lib/security/cacerts for the "general one", who has all the CA for the Authorities and is quite important.

Categories

Resources