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:
-
Using the Java command line arguments:
-Djavax.net.ssl.trustStore=path_to_truststore_file -Djavax.net.ssl.trustStorePassword=mypassword
-
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");
-
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.