Secure Java Connections by Default

MySQL Connector/Java 5.1.38 was released earlier this week, and it includes a notable improvement related to secure connections.  Here’s how the change log describes it:

When connecting to a MySQL server 5.7 instance that supports TLS, Connector/J now prefers a TLS over a plain TCP connection.

This mirrors changes made in 5.7 to the behavior of MySQL command-line clients and libmysql client library.  Coupled with the streamlined/automatic generation of TLS key material to ensure TLS availability in MySQL Server 5.7 deployments, this is an important step towards providing secure communication in default deployments.

Demonstration

This is easy to demonstrate – just take a TLS-enabled MySQL Server 5.7 deployment, and connect a Java application to it.  Try once with Connector/Java 5.1.38, and again with an earlier version.  No configuration is required – the result using the 5.1.38 version of the driver results in a TLS connection.  Here’s a sample program:

String URL = "jdbc:mysql://localhost:3306";
Properties props = new Properties();
props.setProperty("user", "root");
Connection c = DriverManager.getConnection(URL, props);;
ResultSet rs = c.createStatement().executeQuery("SHOW SESSION STATUS LIKE 'Ssl_cipher_list'");
System.out.println("Enabled cipher suites:");
while (rs.next()){
  System.out.println(rs.getString(2));
}
rs = c.createStatement().executeQuery("SHOW SESSION STATUS LIKE 'Ssl_cipher'");
System.out.println("Cipher suite in use:");
while (rs.next()){
  System.out.println(rs.getString(2));
}

When referencing Connector/Java 5.1.38 and pointed at MySQL Enterprise Server 5.7.10, the output looks like the following:

Enabled cipher suites:
ECDHE-ECDSA-AES128-GCM-SHA256:ECDHE-ECDSA-AES256-GCM-SHA384...
Cipher suite in use:
AES128-SHA256

Using an earlier version of Connector/Java, the results will be empty, indicating no SSL/TLS is in use for the connection.

Notes

It’s important to note that this default use of TLS does no identify verification – it simply ensures that the bytes written to the network are encrypted.  Truly secure connections require knowing that Connector/Java is exchanging information with the server you expect it to, and not some active man-in-the-middle attacker that’s impersonating the server.  This means configuring Connector/Java with the necessary certificates to validate the server identity – a process that still requires action during application deployment.  The excellent MySQL reference manual provides guidance on how to accomplish this task.

As shown in the example above, the default cipher suite selected is AES128-SHA256, which is part of the TLSv1.2 specification.  Support for various TLS versions differs based on the JRE version used.  Make sure you know the capabilities of the JDK you are using before restricting specific TLS versions.  When first running the test above, Eclipse was using JRE 1.6.0_45 instead of JRE 1.8.0_65 I expected, and was connecting using TLSv1.0 ciphers.  When MySQL Server was configured to only allow TLSv1.1 and TLSv1.2, I received the following Exception:

Caused by: javax.net.ssl.SSLException: Unsupported record version Unknown-0.0
	at com.sun.net.ssl.internal.ssl.InputRecord.readV3Record(InputRecord.java:504)

Usage of older JREs should be assessed before disabling TLSv1.0 – fortunately, PERFORMANCE_SCHEMA makes it easy to survey client JREs without having to inspect every application server.

Conclusion

The combination of MySQL Server 5.7 and Connector/Java 5.1.38 help protect your data in transit, and limit the amount of configuration required to benefit from secure connections.  Some configuration is still required for protection against active network hackers, and care should be exercised before disabling TLSv1.0, as some older Java versions lack support and connections may fail as a result.

Leave a Reply

Your email address will not be published. Required fields are marked *

Time limit is exhausted. Please reload CAPTCHA.