Documentation Home
Connectors and APIs Manual
Download this Manual
PDF (US Ltr) - 4.5Mb
PDF (A4) - 4.5Mb


3.5.9.1 Setting up Server Authentication

Server authentication via server certificate verification is enabled when the Connector/J connection property sslMode is set to VERIFY_CA or VERIFY_IDENTITY. If sslMode is not set, server authentication via server certificate verification is enabled when the legacy properties useSSL AND verifyServerCertificate are both true.

Certificates signed by a trusted CA.  When server authentication via server certificate verification is enabled, if no additional configurations are made regarding server authentication, Java verifies the server certificate using its default trusted CA certificates, usually from $JAVA_HOME/lib/security/cacerts.

Using self-signed certificates.  It is pretty common though for MySQL server certificates to be self-signed or signed by a self-signed CA certificate; the auto-generated certificates and keys created by the MySQL server are based on the latter—that is, the server generates all required keys and a self-signed CA certificate that is used to sign a server and a client certificate. The server then configures itself to use the CA certificate and the server certificate. Although the client certificate file is placed in the same directory, it is not used by the server.

To verify the server certificate, Connector/J needs to be able to read the certificate that signed it, that is, the server certificate that signed itself or the self-signed CA certificate. This can be accomplished by either importing the certificate (ca.pem or any other certificate) into the Java default truststore (although tampering the default truststore is not recommended) or by importing it into a custom Java truststore file and configuring the Connector/J driver accordingly. Use Java's keytool (typically located in the bin subdirectory of your JDK or JRE installation) to import the server certificates:

$> keytool -importcert -alias MySQLCACert -file ca.pem \
    -keystore truststore -storepass mypassword

Supply the proper arguments for the command options. If the truststore file does not already exist, a new one will be created; otherwise the certificate will be added to the existing file. Interaction with keytool looks like this:

Owner: CN=MySQL_Server_8.4.0_Auto_Generated_CA_Certificate
Issuer: CN=MySQL_Server_8.4.0_Auto_Generated_CA_Certificate
Serial number: 1
Valid from: Thu Mar 07 11:37:33 WET 2024 until: Sun Mar 05 11:37:33 WET 2034
Certificate fingerprints:
	 SHA1: 43:12:0F:96:1A:09:1C:D2:5B:62:7A:2A:55:6C:62:6A:84:5F:78:E4
	 SHA256: 7D:86:18:FF:06:A7:DF:A7:7C:D0:07:AB:96:1A:51:FD:02:4F:32:BF:1C:51:35:42:27:81:53:0A:8F:D3:56:39
Signature algorithm name: SHA256withRSA
Subject Public Key Algorithm: 2048-bit RSA key
Version: 3
Extensions: 
#1: ObjectId: 2.5.29.19 Criticality=true
BasicConstraints:[
  CA:true
  PathLen:2147483647
]
Trust this certificate? [no]:  yes
Certificate was added to keystore

The output of the command shows all details about the imported certificate. Make sure you remember the password you have supplied. Also, be mindful that the password will have to be written as plain text in your Connector/J configuration file or application source code.

The next step is to configure Java or Connector/J to read the truststore you just created or modified. This can be done by using one of the following three methods:

  1. Using the Java command line arguments:

    -Djavax.net.ssl.trustStore=path_to_truststore_file 
    -Djavax.net.ssl.trustStorePassword=mypassword

  2. Setting the system properties directly in the client code:

    System.setProperty("javax.net.ssl.trustStore","path_to_truststore_file"); 
    System.setProperty("javax.net.ssl.trustStorePassword","mypassword");

  3. Setting the Connector/J connection properties:

    trustCertificateKeyStoreUrl=file:path_to_truststore_file 
    trustCertificateKeyStorePassword=mypassword

Notice that when used together, the connection properties override the values set by the other two methods. Also, whatever values set with connection properties are used in that connection only, while values set using the system-wide values are used for all connections (unless overridden by the connection properties). Setting the connection property fallbackToSystemTrustStore to false prevents Connector/J from falling back to the system-wide truststore setup you created using method (1) or (2) when method (3) is not used.

With the above setup and the server authentication enabled, all connections established are going to be SSL-encrypted, with the server being authenticated in the SSL handshake process, and the client can now safely trust the server it is connecting to.

For X-Protocol connections, the connection properties xdevapi.ssl-truststore, xdevapi.ssl-truststore-type, xdevapi.ssl-truststore-password, and xdevapi.ssl-fallbackToSystemTrustStore specify the truststore settings, just like trustCertificateKeyStoreUrl, trustCertificateKeyStoreType, trustCertificateKeyStorePassword, and fallbackToSystemTrustStore do for MySQL-protocol connections; if not explicitly set, xdevapi.ssl-truststore, xdevapi.ssl-truststore-type, xdevapi.ssl-truststore-password, and xdevapi.ssl-fallbackToSystemTrustStore take up the values of trustCertificateKeyStoreUrl, trustCertificateKeyStoreType, trustCertificateKeyStorePassword, and fallbackToSystemTrustStore respectively.

Service Identity Verification.  Beyond server authentication via server certificate verification, when sslMode is set to VERIFY_IDENTITY, Connector/J also performs host name identity verification by checking whether the host name that it uses for connecting matches the Common Name value in the server certificate.