The server may want to authenticate a client and require the client to provide an SSL certificate to it, which it verifies against its known certificate authorities or performs additional checks on the client identity if needed (see CREATE USER SSL/TLS Options for details). In that case, Connector/J needs to have access to the client certificate, so it can be sent to the server while establishing new database connections. This is done using the Java keystore files.
To allow client authentication, the client connecting to the server must have its own set of keys and an SSL certificate. The client certificate must be signed so that the server can verify it. While you can have the client certificates signed by official certificate authorities, it is more common to use an intermediate, private, CA certificate to sign client certificates. Such an intermediate CA certificate may be self-signed or signed by a trusted root CA. The requirement is that the server knows a CA certificate that is capable of validating the client certificate.
Some MySQL server builds are able to generate SSL keys and
certificates for communication encryption, including a
certificate and a private key (contained in the
client-cert.pem
and
client-key.pem
files), which can be used
by any client. This SSL certificate is already signed by the
self-signed CA certificate ca.pem
, which
the server may have already been configured to use.
If you do not want to use the client keys and certificate files generated by the server, you can also generate new ones using the procedures described in Creating SSL and RSA Certificates and Keys. Notice that, according to the setup of the server, you may have to reuse the already existing CA certificate the server is configured to work with to sign the new client certificate, instead of creating a new one.
Once you have the client private key and certificate files you want to use, you need to import them into a Java keystore so that they can be used by the Java SSL library and Connector/J. The following instructions explain how to create the keystore file:
Convert the client key and certificate files to a PKCS #12 archive:
$> openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem \ -name "mysqlclient" -passout pass:mypassword -out client-keystore.p12
Import the client key and certificate into a Java keystore:
$> keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 \ -srcstorepass mypassword -destkeystore keystore -deststoretype JKS -deststorepass mypassword
Supply the proper arguments for the command options. If the keystore file does not already exist, a new one will be created; otherwise the certificate will be added to the existing file. Output by keytool looks like this:
Entry for alias mysqlclient successfully imported. Import command completed: 1 entries successfully imported, 0 entries failed or cancelled
Make sure you remember the password you have chosen. Also, be mindful that the password will have to be written as plain text in your Connector/J configuration file or application source code.
After the step, you can delete the PKCS #12 archive
(
in the example).
client-keystore.p12
The next step is to configure Java or Connector/J so that it reads the keystore 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.keyStore=path_to_keystore_file -Djavax.net.ssl.keyStorePassword=mypassword
Setting the system properties directly in the client code:
System.setProperty("javax.net.ssl.keyStore","path_to_keystore_file"); System.setProperty("javax.net.ssl.keyStorePassword","mypassword");
Through Connector/J connection properties:
clientCertificateKeyStoreUrl=file:path_to_truststore_file clientCertificateKeyStorePassword=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
fallbackToSystemKeyStore
to
false
prevents Connector/J from falling
back to the system-wide keystore setup you created using
method (1) or (2) when method (3) is not used.
With the above setups, all connections established are going to be SSL-encrypted with the client being authenticated in the SSL handshake process, and the server can now safely trust the client that is requesting a connection to it.
For X-Protocol connections, the connection properties
xdevapi.ssl-keystore
,
xdevapi.ssl-keystore-type
,
xdevapi.ssl-keystore-password
, and
xdevapi.ssl-fallbackToSystemKeyStore
specify the keystore settings, just like
trustCertificateKeyStoreUrl
,
trustCertificateKeyStoreType
,
trustCertificateKeyStorePassword
, and
fallbackToSystemTKeyStore
do for
MySQL-protocol connections; if not explicitly set,
xdevapi.ssl-keystore
,
xdevapi.ssl-keystore-type
,
xdevapi.ssl-keystore-password
, and
xdevapi.ssl-fallbackToSystemKeyStore
take
up the values of
clientCertificateKeyStoreUrl
,
clientCertificateKeyStoreType
,
clientCertificateKeyStorePassword
, and
fallbackToSystemKeyStore
respectively.