This document explains how to configure the MariaDB Java driver to support TLS/SSL.
Data can be encrypted during transfer using the Transport Layer Security (TLS) protocol. TLS/SSL permits transfer encryption and, optionally, server and client identity validation.
The term SSL (Secure Sockets Layer) is often used interchangeably with TLS, although strictly-speaking the SSL protocol is the predecessor of TLS, and is not implemented as it is now considered insecure.
To ensure that SSL is correctly configured on the server, the query "SELECT @@have_ssl;" must return YES. If not, please refer to the server documentation.
Connecting to a server that doesn't support TLS with the TLS option set, an exception "Trying to connect with SSL, but SSL not enabled in the server" will be thrown.
TLS Protocol Version SelectionThe MariaDB Java driver by default uses Java's default supported protocols. If the servers are MariaDB on Unix or version >= 10.2, consider adding the TLSv1.2 protocol. This can be set using the "enabledSslProtocolSuites" option (example: enabledSslProtocolSuites=TLSv1.2, TLSv1.3).
In addition to the protocol, the driver relies on the Java default cipher list. The Java default enabled ciphers are listed here . JAVA allows cipher suites to be removed/excluded from use in the security policy using the Java system property "jdk.tls.disabledAlgorithms." The specific list of ciphers to be used can be set using the "enabledSslCipherSuites" driver option (example: "enabledSSLCipherSuites=TLS_ECDHE_ECDSA_WITH_AES_128_CBC_SHA256,...")
One-way SSL authenticationBy default, the driver can be configured to use TLS even if the authentication user is not explicitly required to use it. However, it is recommended to create a user with the REQUIRE SSL
option to enforce TLS. For details, see CREATE USER to ensure the connector always uses TLS.
Example:
CREATE USER 'myUser'@'%' IDENTIFIED BY 'MyPwd';
GRANT ALL ON db_name.* TO 'myUser'@'%' REQUIRE SSL;
Since version 3 of the connector, TLS is enabled with the client-side setting option "sslMode." The following values are supported:
Disable: Do not use SSL/TLS (default)
Trust: Only use SSL/TLS for encryption. Do not perform certificate or hostname verification.
verify-ca: Use SSL/TLS for encryption and perform certificate verification, but do not perform hostname verification.
verify-full:Use SSL/TLS for encryption, certificate verification, and hostname verification. This is the standard TLS behavior. Aliases "true"/"1" are possible like "sslMode=true."
Before connector 3 version, other options were used in order to use TLS:
useSsl: boolean, indicate if TLS has to be enable.
trustServerCertificate: boolean, when enable with useSsl=true, corresponds to sslMode=trust
disableSslHostnameVerification: boolean, when enable with useSsl=true and trustServerCertificate is not enable, corresponds to sslMode=verify-ca
To ensure TLS is enabled server-side, first try with the option "sslMode=trust."
try (Connection con = DriverManager.getConnection("jdbc:mariadb://localhost/myDb?user=myUser&password=MyPwd"
+ "&sslMode=trust")) {
try (Statement stmt = con.createStatement()) {
stmt.execute("select 1");
}
}
This configuration is not safe for production. While all data exchanges are encrypted, the server’s identity is not verified, leaving the connection vulnerable to man-in-the-middle attacks by malicious servers.
To ensure the server’s identity is validated, the client must trust the server’s root and intermediate certificates. This can be accomplished in several ways:
Java includes a default truststore containing certificates from well-known Certificate Authorities (CAs), such as Let’s Encrypt (added in Java 8u101), VeriSign, Entrust, and GTE CyberTrust. If the server’s certificate chain is signed by a root CA present in this default truststore, no additional client-side configuration is required. The default truststore location is defined by the system property javax.net.ssl.trustStore
.
Alternatively, you can explicitly provide the server’s certificate using the serverSslCert
option.
Starting with Connector version 3.4+ and MariaDB Server 11.4+, zero-configuration TLS encryption is supported. For details, see the dedicated chapter.
By default, when sslMode
is enabled (and not set to DISABLED
), the connector will use the certificate specified in serverSslCert
if provided, or fall back to the default truststore if not. This fallback behavior can be disabled by setting the fallbackToSystemTrustStore
option to false
.
Java trustStore is a file that contains certificates of trusted SSL servers or certificate authorities trusted to identify servers. Truststore can be protected by a password.
The Java search order for locating the trust store is
system property "javax.net.ssl.trustStore"
$JAVA_HOME/lib/security/jssecacerts
$JAVA_HOME/lib/security/cacerts (shipped by default)
To include a certificate from a CA that is not already in the truststore, first locate your system’s default truststore. By default, it can be found at: $JAVA_HOME/jre/lib/security/cacerts
.
//copy the java truststore to jssecacerts
cp $JAVA_HOME/jre/lib/security/cacerts $JAVA_HOME/jre/lib/security/jssecacerts
//add your certificate to the truststore
keytool -importcert -file myCA-root.cer -alias myCA -keystore /usr/java/default/jre/lib/security/jssecacerts -storepass changeit
If you’re referring to the database connection string from our earlier example, switching sslMode
to "verify-full"
just means updating that property in your config or connection URL.
try (Connection con = DriverManager.getConnection("jdbc:mariadb://localhost/myDb?user=myUser&password=MyPwd"
+ "&sslMode=verify-full")) {
try (Statement stmt = con.createStatement()) {
stmt.execute("select 1");
}
}
Provide the certificate directly
The serverSslCert
option specifies the location of the server’s SSL certificate. The location can be provided in one of the following three formats:
Full file path – e.g., serverSslCert=/path/to/cert.pem
Classpath-relative path – e.g., serverSslCert=classpath:relative/cert.pem
(relative to the current classpath)
Inline certificate string – a verbatim DER-encoded certificate, e.g., "-----BEGIN CERTIFICATE-----..."
Example :
try (Connection con = DriverManager.getConnection("jdbc:mariadb://localhost/myDb?user=myUser&password=MyPwd&serverSslCert=/path/to/cert.pem&&sslMode=verify-full")) {
try (Statement stmt = con.createStatement()) {
stmt.execute("select 1");
}
}
Zero-configuration TLS encryption
In MariaDB Server 11.4, TLS configuration is simpler than before. When connecting with MariaDB Connector/J 3.4 or later, you can enable SSL encryption by setting sslMode=verify-full
—no other SSL parameters are needed. During the TLS handshake, the server provides its certificate, and the client confirms the server’s identity using the certificate fingerprint along with password hashing. For this verification to succeed, the password must not be empty.
Mutual SSL authentication, also known as certificate-based mutual authentication, is a process where two parties verify each other’s identity by validating the digital certificates presented, ensuring that both sides can trust the authenticity of the other.
To enable mutual authentication, the user must be created with "REQUIRE X509" so the server asks the driver for client certificates. See CREATE USER for more details.
Example:
CREATE USER 'myUser'@'%' IDENTIFIED BY 'MyPwd';
GRANT ALL ON db_name.* TO 'myUser'@'%' REQUIRE X509;
If the user is not set with REQUIRE X509, only one- way authentication will be done
The client (driver) must also have its own certificate along with the corresponding private key. If the driver does not present a certificate and the user account is configured with REQUIRE X509
, the server will respond with a simple “Access denied for user” message.
In Java, the client certificate and its private key are stored in a keystore file. A keystore is similar to a truststore—in fact, they are often the same file.
Example: Generating a keystore in JKS format
# generate a keystore with the client cert & key
openssl pkcs12 \
-export \
-in "${clientCertFile}" \
-inkey "${clientKeyFile}" \
-out "${tmpKeystoreFile}" \
-name "mariadbAlias" \
-passout pass:kspass
# convert PKSC12 to JKS
keytool \
-importkeystore \
-deststorepass kspass \
-destkeypass kspass \
-destkeystore "${clientKeystoreFile}" \
-srckeystore ${tmpKeystoreFile} \
-srcstoretype PKCS12 \
-srcstorepass kspass \
-alias "mariadbAlias"
Like the truststore, you can use the Java default keystore without requiring any additional options. Alternatively, you can specify a dedicated keystore by using the keyStore
option to provide its location and the keyStorePassword
option to set its password. If the JKS keystore includes a separate password for a specific key, you can set it with the keyPassword
option.
If you encounter the error:
pgsqlCopyEditjava.sql.SQLException: Trying to connect with ssl, but ssl not enabled in the server
It means SSL is disabled on the server. Since the connection was made with the useSSL=true
option, it failed. To verify the SSL status on the server, run:
sqlCopyEditSHOW VARIABLES LIKE '%ssl%';
Server certificate not provided to the client
When the driver attempts an SSL connection without a provided certificate, or when trustServerCertificate=true
is not set, the connection will fail with an exception similar to:
luaCopyEditCaused by: sun.security.validator.ValidatorException: PKIX path building failed:
sun.security.provider.certpath.SunCertPathBuilderException:
unable to find valid certification path to requested target
Solution:
Not recommended: Set the sslMode
option to trust
.
Add the server certificate to the driver (see documentation above).
pgsqlCopyEditjava.sql.SQLInvalidAuthorizationSpecException: Could not connect: Access denied for user
This can occur due to:
Incorrect username or password.
SSL requirements are set for the user that the connection does not meet. You can check the SSL settings for a user with:
sqlCopyEditSELECT SSL_TYPE, SSL_CIPHER, X509_ISSUER, X509_SUBJECT
FROM mysql.user u
WHERE u.User = '';
RetroSearch is an open source project built by @garambo | Open a GitHub Issue
Search and Browse the WWW like it's 1997 | Search results from DuckDuckGo
HTML:
3.2
| Encoding:
UTF-8
| Version:
0.7.4