MySQL JDBC через проблему SSL - PullRequest
2 голосов
/ 12 января 2011

Как можно заставить MySQL JDBC работать по SSL (с проверкой сертификатов X509)?

У меня есть самостоятельно созданные сертификаты, как описано в руководстве MySQL, в Using SSL for Secure Connections, в частности:

# Create CA certificate
shell> openssl genrsa 2048 > ca-key.pem
shell> openssl req -new -x509 -nodes -days 1000 \
         -key ca-key.pem > ca-cert.pem

# Create server certificate
shell> openssl req -newkey rsa:2048 -days 1000 \
         -nodes -keyout server-key.pem > server-req.pem
shell> openssl x509 -req -in server-req.pem -days 1000 \
         -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > server-cert.pem

# Create client certificate
shell> openssl req -newkey rsa:2048 -days 1000 \
         -nodes -keyout client-key.pem > client-req.pem
shell> openssl x509 -req -in client-req.pem -days 1000 \
         -CA ca-cert.pem -CAkey ca-key.pem -set_serial 01 > client-cert.pem

После выдачи GRANT ALL ON *.* TO vic@localhost IDENTIFIED BY '12345' REQUIRE X509; я могу подключиться к MySQL по команде-line:

mysql -u vic -p --ssl-ca=ca-cert.pem --ssl-cert=client-cert.pem --ssl-key=client-key.pem mysql
...

mysql>  SHOW STATUS LIKE 'Ssl_cipher';
+---------------+--------------------+
| Variable_name | Value              |
+---------------+--------------------+
| Ssl_cipher    | DHE-RSA-AES256-SHA |
+---------------+--------------------+

Однако, когда я пытаюсь запустить тест Java, я получаю ошибку аутентификации: Access denied for user 'vic'@'localhost' (using password: YES).Код следующий:

public class Launcher {
    public static void main(String[] args) throws DbException, SQLException, ClassNotFoundException {
        StringBuffer sb = new StringBuffer("jdbc:mysql://localhost/bt?useSSL=true&");
        sb.append("user=vic&password=12345&");
        sb.append("clientCertificateKeyStorePassword=123456&");
        sb.append("clientCertificateKeyStoreType=JKS&");
        sb.append("clientCertificateKeyStoreUrl=file:///home/vic/tmp/client-keystore&");
        sb.append("trustCertificateKeyStorePassword=123456&");
        sb.append("trustCertificateKeyStoreType=JKS&");
        sb.append("trustCertificateKeyStoreUrl=file:///home/vic/tmp/ca-keystore");

        Class.forName("com.mysql.jdbc.Driver");
        Connection c = DriverManager.getConnection(sb.toString());

        Statement st = c.createStatement();
        ResultSet rs = st.executeQuery("SELECT * FROM test_table");
        while (rs.next()) {
            System.out.println(rs.getInt("id"));
        }
        rs.close(); st.close(); c.close();
    }
}

И вот как я подготовил файлы хранилища ключей Java:

keytool -import -alias mysqlServerCACert -file ca-cert.pem -keystore ca-keystore
keytool -import -file client-cert.pem -keystore client-keystore -alias client-key

ОБНОВЛЕНИЕ Я могу подключиться через SSL через JDBC, если я использую 'пользователь root вместо пользователя vic.Затем следующий код

    Statement st = c.createStatement();
    ResultSet rs = st.executeQuery("SHOW STATUS LIKE 'Ssl_cipher';");
    while (rs.next()) {
        System.out.println(rs.getString(1));
        System.out.println(rs.getString(2));
    }

печатает

Ssl_cipher
DHE-RSA-AES128-SHA

Но я не могу использовать root в рабочей среде, и мне интересно, почему JDBC использует AES128, тогда как клиент командной строки mysql использует AES256.

UPDATE2 После того, как я изменил ssl_type на X509 в user таблице для root@localhost, запрашивая полную авторизацию клиента, я получаю такое же поведение для root, как и для vic -невозможно войти через JDBC.

UPDATE3 Если я использую REQUIRE SSL вместо REQUIRE X509 в операторе GRANT, код работает.Можно ли заставить X509 работать?

Ответы [ 4 ]

3 голосов
/ 03 июля 2013

Поддержка самозаверяющих сертификатов была недавно добавлена ​​в драйвер JDBC MariaDB (который также работает для подключения к MySQL).Последняя версия (1.1.3 на момент написания этой статьи) также позволяет вам напрямую указывать сертификат сервера во время выполнения, чтобы вам не нужно было предварительно настраивать хранилища ключей или импортировать сертификаты.

Два свойства для установкиuseSSL и serverSslCert.Последним может быть либо сам сертификат (строковое значение), либо путь к файлу, который содержит сертификат (полный путь или относительный путь к классу):

String url = "jdbc:mysql://" + host + ":" + port + "/" + database;
Properties info = new Properties();
info.setProperty("user", username);
info.setProperty("password", password);
info.setProperty("useSSL", "true");
info.setProperty("serverSslCert", "classpath:server.crt");
Connection conn = DriverManager.getConnection(url, info);

Для полного рабочего примера подключениясмотрите здесь: https://github.com/properssl/java-jdbc-mariadb

0 голосов
/ 27 февраля 2016

Кажется, что у водителей MariaDB есть тестовый класс, который проходит по всем сценариям, включая 'REQUIRES X509'.

https://github.com/MariaDB/mariadb-connector-j/blob/master/src/test/java/org/mariadb/jdbc/SslTest.java

0 голосов
/ 16 июля 2012

Я могу подключиться, даже не указав свойства сертификата клиента, когда пользователь настроен только с ТРЕБУЕМЫМ SSL.

0 голосов
/ 18 марта 2011

Я остановился на использовании REQUIRE SSL.Если кто-то знает, как заставить X509 работать с JDBC, эта информация будет признательна.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...