Connecting SSL to MySQL Server Using Java

I am trying to connect to a MySQL server using Java over SSL. I get the following exception:

com.mysql.jdbc.exceptions.jdbc4.MySQLNonTransientConnectionException: Cannot connect to MySQL server on www.mysite.com:3306. Make sure that there is a MySQL server running on the machine/port you are trying to connect to and that the machine this software is running on is able to connect to this host/port (ie not firewalled). Also make sure that the server has not been started with the --skip-networking flag. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.mysql.jdbc.Util.handleNewInstance(Util.java:407) at com.mysql.jdbc.Util.getInstance(Util.java:382) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:1013) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:987) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:982) at com.mysql.jdbc.SQLError.createSQLException(SQLError.java:927) at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:827) at com.mysql.jdbc.JDBC4Connection.<init>(JDBC4Connection.java:47) at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) at sun.reflect.NativeConstructorAccessorImpl.newInstance(Unknown Source) at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(Unknown Source) at java.lang.reflect.Constructor.newInstance(Unknown Source) at com.mysql.jdbc.Util.handleNewInstance(Util.java:407) at com.mysql.jdbc.ConnectionImpl.getInstance(ConnectionImpl.java:378) at com.mysql.jdbc.NonRegisteringDriver.connect(NonRegisteringDriver.java:305) at java.sql.DriverManager.getConnection(Unknown Source) at java.sql.DriverManager.getConnection(Unknown Source) at java.lang.Thread.run(Unknown Source) Caused by: java.lang.UnsupportedOperationException: The method shutdownInput() is not supported in SSLSocket at sun.security.ssl.BaseSSLSocketImpl.shutdownInput(Unknown Source) at com.mysql.jdbc.MysqlIO.forceClose(MysqlIO.java:506) at com.mysql.jdbc.ConnectionImpl.connectOneTryOnly(ConnectionImpl.java:2404) at com.mysql.jdbc.ConnectionImpl.createNewIO(ConnectionImpl.java:2163) at com.mysql.jdbc.ConnectionImpl.<init>(ConnectionImpl.java:794) ... 25 more 

This is my code:

 properties = new Properties(); properties.put("user", "myuser"); properties.put("password", "mypassword"); properties.put("useSSL", "true"); System.setProperty("javax.net.ssl.keyStore", "keystore.jks"); System.setProperty("javax.net.ssl.keyStorePassword", "keystorepass"); System.setProperty("javax.net.ssl.trustStore", "truststore.jks"); System.setProperty("javax.net.ssl.trustStorePassword", "truststorepass"); connection = DriverManager.getConnection("jdbc:mysql://www.mysite.com:3306/mydatabase", properties); 

More details

Creating a keystore and trust store

I created a keystore and trust store as follows:

 openssl pkcs12 -export -inkey client-key.pem -in client-cert.pem > keystore.p12 keytool -importkeystore -srckeystore keystore.p12 -srcstoretype pkcs12 -destkeystore keystore.jks -deststoretype JKS openssl x509 -outform der -in ca.pem -out ca.der keytool -import -file ca.der -alias myCA -keystore truststore.jks 

Original certificates

This is a list of my certificates:

  • ca.pem
  • client-key.pem
  • client-cert.pem
  • Server-key.pem
  • Server-cert.pem

Connection without SSL

The following code works just fine, just to demonstrate that I can connect to a MySQL server in Java:

 properties = new Properties(); properties.put("user", "myuser"); properties.put("password", "mypassword"); connection = DriverManager.getConnection("jdbc:mysql://www.mysite.com:3306/mydatabase", properties); 

SSL connection works when using MySQL on the command line

I start the MySQL server using the command:

 mysqld --ssl-ca=ca.pem --ssl-cert=server-cert.pem --ssl-key=server-key.pem 

Then I connect to it using the MySQL command:

 mysql --host=www.mysite.com --user=myuser --password=mypassword --database=mydatabase --ssl-ca=ca.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem 

This works, and after the SHOW STATUS LIKE 'Ssl_cipher' I get the correct result:

 +---------------+--------------------+ | Variable_name | Value | +---------------+--------------------+ | Ssl_cipher | DHE-RSA-AES256-SHA | +---------------+--------------------+ 
+6
source share
1 answer

If you have this problem, at least make sure your CA certificate is imported into the JRE key store!

keytool -import -noprompt -trustcacerts -alias & uniqueCAAlias> -file ca.pem -keystore <pathtocacerts>

(You may need to change the file name "ca.pem" to your own CA certificate certificate name)

Remember to keep <uniqueCAAlias> something unique. Also change the <pathtocacerts> so that it matches the path of your JVM. Note that this is most likely the highest version of the JRE, but it may be the JRE SDK or another JRE that is installed (for example, "C: \ Program Files \ Java \ jre1.8.0_25 \ lib \ security \ cacerts ")

You will need to enter a password for the truststore JVM: this password is always "changeit".

I can not guarantee that this will solve the problem, but it was an important step that I took while working on it, and I got it at the end.

0
source

All Articles