allowPublicKeyRetrieval option in the MySQL JDBC connector


The allowPublicKeyRetrieval option in the MySQL JDBC connector is used to control whether the client is allowed to request the public key of the server during an SSL connection. By default, this option is set to false to enhance security and prevent potential man-in-the-middle attacks. However, in some cases, it may be necessary to set this option to true to enable certain features or compatibility with older applications.

Context:

  • SSL/TLS Handshake: When a client (like an application using MySQL Connector/J) establishes an SSL/TLS connection with a MySQL server, it involves a handshake process where encryption keys and certificates are exchanged to ensure a secure connection.
  • Server Certificate: The server presents a certificate to the client during the handshake. This certificate includes the server’s public key used for encryption and verification.

Why is allowPublicKeyRetrieval set to false by default?

Setting allowPublicKeyRetrieval to false prevents the client from retrieving the server’s public key, which is essential for verifying the server’s identity. This additional layer of security helps protect against man-in-the-middle attacks, where an attacker could intercept the communication between the client and the server and impersonate the server.

If you attempt to retrieve the public key when allowPublicKeyRetrieval to false then you will get the following Exception:

Exception in thread "main" java.sql.SQLNonTransientConnectionException: Public Key Retrieval is not allowed at
     com.mysql.cj.jdbc.exceptions.SQLError.createSQLException(SQLError.java:108) at 

When would I need to set allowPublicKeyRetrieval to true?

There are a few scenarios where setting allowPublicKeyRetrieval to true might be necessary:

  1. Using older MySQL versions: MySQL versions prior to 8.0.12 required the client to retrieve the server’s public key for certain features, such as using the XA protocol for distributed transactions.
  2. Enabling compatibility with older applications: Some older applications may not work correctly when the server’s public key is not available. Setting allowPublicKeyRetrieval to true can help these applications connect to the MySQL server.
  3. Using custom authentication methods: Some custom authentication methods may require the client to retrieve the server’s public key.

Example usage:

String jdbcUrl = "jdbc:mysql://localhost:3306/mydb?allowPublicKeyRetrieval=true";
Connection conn = DriverManager.getConnection(jdbcUrl, "username", "password");

Is it safe to set allowPublicKeyRetrieval to true?

Setting allowPublicKeyRetrieval to true does introduce a slight security risk, as it allows the client to retrieve the server’s public key. This could potentially be used by an attacker to intercept the communication and decrypt the data. However, this risk is mitigated by using a strong SSL/TLS cipher suite, which provides encryption of the data exchanged between the client and the server.

Recommendations for using allowPublicKeyRetrieval

If you need to set allowPublicKeyRetrieval to true, it’s important to carefully weigh the potential risks and benefits. Consider using a strong cipher suite and only enabling this option when absolutely necessary. Additionally, keep your MySQL server and JDBC driver up to date to ensure that you have the latest security features and bug fixes.

Conclusion

In essence, the allowPublicKeyRetrieval option in MySQL Connector/J relates to how SSL/TLS connections handle public key retrieval during the initial SSL/TLS handshake. This option influences whether the client requests and uses the public key for the server certificate during the SSL/TLS handshake process. To learn how to configure MySQL in WildFly, check this article: Configuring a Datasource with MySQL on WildFly