Recent changes to support better security by increasing strength of Diffie-Hellman cipher suites from 512-bit to 2048-bit were introduced to MySQL Server 5.7. While this change enhances security, it is an aggressive change in that 2048-bit DH ciphers are not universally supported. This has become a problem specifically for Java users, as only Java 8 JRE (currently) supports DH ciphers greater than 1024 bits. Making the problem more acute, this change was back-ported from MySQL Server 5.7 to the recent 5.6.26 and 5.5.45 releases in response to a community bug report. This blog post will identify affected applications, existing workarounds, and our plans to provide a more permanent solution in upcoming maintenance releases.
Because the MySQL Server is trying to negotiate a DH cipher size (2048) that’s larger than what many JREs can support (1024), affected programs will see an error trying to establish a connection to MySQL Server. The important parts of the stack trace look like this:
com.mysql.jdbc.exceptions.jdbc4.CommunicationsException: Communications link failure The last packet successfully received from the server was 480 milliseconds ago. The last packet sent successfully to the server was 474 milliseconds ago. at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method) ... Caused by: javax.net.ssl.SSLException: java.lang.RuntimeException: Could not generate DH keypair ... Caused by: java.lang.RuntimeException: Could not generate DH keypair ... Caused by: java.security.InvalidAlgorithmParameterException: Prime size must be multiple of 64, and can only range from 512 to 1024 (inclusive)
The information regarding the DH keypair is found in a nested Exception – if you only inspect the top-level Exception, it will have only generic information:
Error Message:Communications link failure
If your application (or framework) hides the full stack trace when writing to the application log, the cause will likely be difficult to determine. Connector/Java developers noticed this, and added useful additional text to the error message, starting in Connector/Java 5.1.35:
Error Message:The driver was unable to create a connection due to a possible incompatibility between the default enabled cipher suites in this JVM and the security layer provided by the server.
MySQL Community version 5.7.6 and above require a 2048 bit key during DH key exchange. This was not supported in Java before v8. Setting the connection property ‘enabledSSLCipherSuites=TLS_RSA_WITH_AES_128_CBC_SHA,SSL_RSA_WITH_RC4_128_SHA,SSL_RSA_WITH_3DES_EDE_CBC_SHA,SSL_RSA_WITH_RC4_128_MD5,SSL_RSA_WITH_DES_CBC_SHA’ uses RSA key exchange instead.
For users of recent MySQL Connector/Java releases, this additional information will prove useful in diagnosing this problem.
Listed below are characteristics of deployment environments which are affected (all must be met):
- MySQL Server version is one of the below:
- 5.7.6 – 5.7.8
- JRE is one of the below:
- Java 8, before b56
- Java 7 or earlier
- SSL/TLS connections in use
- Not using an external JSSE provider (e.g., Bouncy Castle)
Additionally, DH ciphersuites must be enabled. They are by default, and while DBAs could theoretically restrict their use by specifying values for the –ssl-cipher server option that don’t include them, DH ciphersuites uniquely provide perfect forward secrecy among MySQL-supported options.
As mentioned above, use of DH ciphersuites can be restricted. This can be done on the server side using –ssl-cipher, and can be done on the client side with the enabledSSLCipherSuites property added in Connector/Java 5.1.35. as described in the error message text cited earlier. The configuration cited in the error message text avoids the Exception during connection, but it also negotiates a ciphersuite other than DH (thus abandoning PFS).
Applications which use (or can use) Java 8 should ensure that they are running at least b56 or later before upgrading MySQL Server to an affected version where SSL is used.
It is very likely that MySQL Server 5.5 and 5.6 will have the DH length reduced from 2048 to 1024 to eliminate incompatibility with legacy Java applications. Additionally, we are evaluating making this a runtime configuration option for all versions of MySQL Server, instead of the compile-time option that currently exists.