10
votes

I am connecting to MySQL over SSL from my Java application. I have configured MYSQL to support SSL and generated client certificates. I have imported server CA certificate and client certificate into keystore. This is how my code currently looks like

    String url = "jdbc:mysql://127.0.0.1:3306/MySampleDb? verifyServerCertificate =true&useSSL=true&requireSSL=true"

    System.setProperty("javax.net.ssl.keyStore","/home/cert/keystore");
    System.setProperty("javax.net.ssl.keyStorePassword","password");
    System.setProperty("javax.net.ssl.trustStore","/home/cert/truststore");
    System.setProperty("javax.net.ssl.trustStorePassword","password");

    Class.forName("com.mysql.jdbc.Driver");
    con = DriverManager.getConnection(url, user, password);

I want to use spring with C3p0 to connect to MYSQL over SSL.This is my spring configuration file which reads parameters from jdbc.properties.

<bean id="dataSource" class="com.mchange.v2.c3p0.ComboPooledDataSource" destroy-method="close">
    <property name="driverClass" value="${jdbc.driver}"/>
    <property name="jdbcUrl" value="${jdbc.url}"/>
    <property name="user" value="${jdbc.username}"/>
    <property name="password" value="${jdbc.password}"/>
    ........
</bean>

How can I configure spring to set properties verifyServerCertificate =true
useSSL=true
requireSSL=true"

Also is it possible to set keyStore and trustStore values in spring config file.

3

3 Answers

15
votes

The value for jdbc.url in jdbc.properties has to be

jdbc:mysql://127.0.0.1:3306/MySampleDb?verifyServerCertificate=true&useSSL=true&requireSSL=true

Those parameters must be added directly to the URL for MySQL. The parameters for keyStore and trustStore should be passed to the JVM at start like so:

-Djavax.net.ssl.keyStore=path_to_keystore_file
-Djavax.net.ssl.keyStorePassword=password
-Djavax.net.ssl.trustStore=path_to_truststore_file
-Djavax.net.ssl.trustStorePassword=password

You can use Spring to set system properties but I'd never use it, it's too cumbersome.

8
votes

It is not necessary to pass keyStore and trustStore to java program or set any system properties as it can be achieved via connection properties per connection!

So you can use different certificated for different connections (and applications if you are in app server).

Original answer: https://stackoverflow.com/a/51879119/173149 Relevant part:

jdbc:mysql://example.com:3306/MYDB?verifyServerCertificate=true&useSSL=true&requireSSL=true&clientCertificateKeyStoreUrl=file:cert/keystore.jks&clientCertificateKeyStorePassword=123456&trustCertificateKeyStoreUrl=file:cert/truststore.jks&trustCertificateKeyStorePassword=123456

It is documented:

1
votes

You can configure the useSSl, requireSSL, and verifyServerCertificate properties of a DataSource by using Java based configuration. The addDataSourceProperty method of the DataSource class gives you the ability, as shown in the below code snippet (you can replace HikariDataSource with a C3p0 instance)

MySQL Connector/J exposes configuration properties for key stores (e.g. trustCertificateKeyStoreUrl), so I assume that addDataSourceProperty can be used for these properties too.

I do not know if the XML configuration schema provides a tag that corresponds to addDataSourceProperty.

public DataSource createPslDataSource(final MyDataSourceProperties myDataSourceProperties) {

    HikariDataSource dataSource = new HikariDataSource();

    dataSource.addDataSourceProperty("useSSL", true);
    dataSource.addDataSourceProperty("requireSSL", true);
    dataSource.addDataSourceProperty("verifyServerCertificate", true);

    dataSource.setJdbcUrl(myDataSourceProperties.getJdbcUrl());
    dataSource.setUsername(myDataSourceProperties.getUsername());
    dataSource.setPassword(myDataSourceProperties.getPassword());

    return dataSource;
}