SSL connection error when connecting to MySQL, using JDBC - java

The problem that we are facing is well documented in https://stackoverflow.com/questions/34189756/warning-about-ssl-connection-when-connecting-to-mysql-database.
We started facing this issue upon transitioning from MySQL 5.6.51 to MySQL 8.0.27.
The fix that is suggested works for us but we have an issue in that we don’t want to update the Java source files to change, for example, from
jdbc:mysql://localhost:3306/Peoples
to
jdbc:mysql://localhost:3306/Peoples?autoReconnect=true&useSSL=false
as suggested in https://stackoverflow.com/a/34449182
Question: Is there some change that we can make to the execution environment of our new target (Ubuntu kernel version 5.4.0-91) such that we need not make changes to the existing Java code?

You could resolve the SSL errors using the other method recommended in the error message itself:
You need either to explicitly disable SSL by setting useSSL=false, or set useSSL=true and provide truststore for server certificate verification.
(emphasis mine)
That is, create a truststore file, and set the path to the truststore file and the password using Java properties. Then you can set those properties without changing code.
See https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html for more details on creating the truststore file and use properties to specify it to your Java app.

Related

How to specify a local custom SSL truststore for JTOpen?

We have a java client (mule app) which is using JTOpen for connecting to the AS400 system.
The connection is secured with SSL. The driver is using the JRE truststore (jssecacerts, cacerts) by default.
We would like to specify a custom truststore for the JTOpen session.
The only way to do this that I found in the documentation is to configure the javax.net.ssl.trustStore system property.
But this is a global property that may affect other applications. So, we are looking for the alternative.
Is there another way of specifying a path to a truststore for JT400, so, that it would not affect other applications running on the same VM system? May be a connection parameter or the driver specific property?

Right way to configure Glassfish SSL certificate nickname?

Glassfish lets to set the SSL certificate nickname through its admin console as it is highlighted in the pic below:
But almost every tutorials in the web mention that it is necessary to replace all occurrences of the default SSL nickname (s1as) with the one will be used(i.e. mydomain.com) in the domain.xml file.
So what is the proper way of setting certificate nickname?
It is very likely that the admin console is just updating the domain.xml file anyway. In either case, it is good practice to avoid modifying the domain.xml file wherever possible. There is no official advice in the Security Guide for GF4 and the only mention of the certificate nickname is:
If you enable secure admin on an SSL-enabled GlassFish Server
installation, secure admin uses the existing value
as the DAS admin alias for secure admin.
https://glassfish.java.net/docs/4.0/security-guide.pdf
Changing the nickname isn't actually necessary, from a functional perspective. When you import your key/cert to the keystores you can just use the same name to replace the existing cert, which is perfectly valid.
Edit: To change alias names with the asadmin command, you can use enable-secure-admin with either --instancealias myNewAlias or --adminalias myOtherNewAlias (or both).
The default for adminalias is s1as and the default for instancealias is glassfish-instance.
http-listener-2 is the default http listener (glassfish or payara) with ssl enabled on port 8181, if you have created another change for it in the bellow command.
asadmin set "configs.config.server-config.network-config.protocols.protocol.http-listener-2.ssl.cert-nickname=yourNickName"

Client Certificate using Weblogic

Background:
I am working on a project that involves the client to authenticate itself (via client certificate). We are trying to launch a third party app which first authenticates the client cert and then launches its app.
We are using Java and SSL hanshake, and our client server is Weblogic 10.x. The client certificate is in PKCS12 format (cannot change this)
This is the piece of code for presenting the certificate:
System.setProperty("javax.net.ssl.keyStore","MyPath/cert.pfx");
System.setProperty("javax.net.ssl.keyStorePassword","MyPwd");
System.setProperty("javax.net.ssl.keyStoreType","PKCS12");
url.openConnection();
Now all this works pretty well from a standalone. The problem starts when we put this on weblogic. Sometimes it works, sometimes 'Client certificate not present' (http 403.7) is returned. I have tried various combinations (including configuring custome keystore on weblogic console) but nothing seems to work. Any idea why would weblogic altogether ignore the SSL settings (it doesnt throw an error even if I set keystore to a non-existent file)? System.setProperty for SSL just appears useless on weblogic!
In Weblogic 12c you also need add the parameter -DUseSunHttpHandler=true in order to tell the weblogic server to use the Sun Http Handlers instead of its own. Therefore you need the following Java VM parameters:
-Djavax.net.ssl.keyStore=MyPath/cert.pfx
-Djavax.net.ssl.keyStoreType=PKCS12
-Djavax.net.ssl.keyStorePassword=MyPwd
-DUseSunHttpHandler=true
Finally found the solution! Weblogic seems to over-ride the keystore configurations if it is done through Java as above. The thing that worked for me was to configure the SSL settings on JVM level, at web-logic start-up.
To make it work, I just added these Java options in the start-script for weblogic:
-Djavax.net.ssl.keyStore=MyPath/cert.pfx
-Djavax.net.ssl.keyStoreType=MyPwd
-Djavax.net.ssl.keyStorePassword=PKCS12
Restarted web-logic and SSL has been working great since then :)

2way ssl with java

I am trying at write a java program that hits a url over ssl, and prints out the response to find out if the application on this port is running or not. We are using 2way ssl. I am fairly new to working with ssl and java security. Right now I am getting this error
Remote host closed connection during handshake
I am using this command to run the program
java -Djavax.net.ssl.trustStore=rs.truststore TmpUtil
Is there a way to find out what am I doing wrong and where exactly is the problem ?
You can generally debug an SSL/TLS connection that uses the JSSE in Java using the javax.net.debug system property. You'll find more details in the documentation.
Since you're after client-certificate authentication, it's most likely that your application needs a keystore to be configured. You'll find some details about the difference between keystore and truststore in this answer, and in the JSSE Reference Guide of course.

How to use the Windows Keystore (MCS) with JDBC?

I am trying to create a java application that uses PKI for authentication. I need to be able to retrieve a certificate from the Microsoft Certificate Store (MCS) and pass it along to an Oracle database (11.2).
I am connecting using the jdbc:oracle:thin driver. After spending quite some time on google I have come up empty.
I've found different properties to change (depending on the article):
set the property javax.net.ssl.keyStoreType = "Windows-MY"
set the javax.net.ssl.keyStore = "Windows-MY"
javax.net.ssl.keyStore should be set to "None" (if using a custom KeyManager which I do not believe will work since by the time it gets into my custom KeyManager I will already be given the certs from a keystore specified in the connection properties).
Of course all of these people are claiming success, but nothing has worked for me. I have tried every example I have been able to find all with no luck. I was able to successfully authenticate when I was using Oracle wallets so I know my certificates are fine. If anyone has done this before and is willing to post some code that would be great.
I know most people are using the Windows keystore with a website and therefore are creating their own SSLContext, but I cannot imagine I am the only one who has wanted to do this using JDBC (which as far as I know does not allow me to provide it an SSLContext).
This is the code that I believe should work, but does not.
DriverManager.registerDriver)new OracleDriver());
String url = "jdbc:oracle:thin:#(DESCRIPTION=(ADDRESS=(PROTOCOL=TCPS)(HOST=host)(PORT=2484))(CONNECT_DATA=(SERVICE_NAME=someName))(SECURITY= (SSL_SERVER_CERT_DN=\"CN=TESTSERVER\")))";
java.util.Properties props = new java.util.Properties();
props.setProperty("javax.net.ssl.keyStoreType", "Windows-MY");
props.setProperty("javax.net.ssl.keyStore", "NONE");
props.setProperty("javax.net.ssl.trustStoreType", "Windows-ROOT");
props.setProperty("javax.net.ssl.trustStore", "NONE");
props.setProperty("oracle.net.ssl_server_dn_match", "true");
props.setProperty("oracle.net.authentication_services", "(TCPS)");
Connection conn = DriverManager.getConnection(url, props);
This code fails with the exception:
java.sql.SQLRecoverableException: IOException: The Network Adapter could not establish the connection
This article should give your more details. Although it doesn't use the system properties, Windows-MY is clearly a store type and it's not file based. Therefore, javax.net.ssl.keyStoreType should be Windows-MY and javax.net.ssl.keyStore should be set to NONE (upper case may matter), see the JSSE Ref Guide (Customization):
javax.net.ssl.keyStore system property
Note that the value NONE may be specified. This setting is appropriate if the keystore is not
file-based (for example, it resides in a hardware token).
You may also need to configure your trust store in a similar way if your server certificate isn't trusted by your default Java trust store.

Categories