2011-01-11 9 views
2

MySQL JDBCをSSL上で動作させる方法(X509証明書の検証を使用) Using SSL for Secure Connectionsで、MySQLのマニュアルに記載されているようMySQL JDBC over SSLの問題

私は具体的には、自分で作成した証明書を持っている:

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 | 
+---------------+--------------------+ 

# 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 [email protected] IDENTIFIED BY '12345' REQUIRE X509;を発行した後、私は、コマンドラインからMySQLに接続することができています

しかし、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キーストアファイルの作成方法は次のとおりです:コードは、以下の私が代わりに「VIC」の「ルート」ユーザを使用する場合、私はJDBC経由でSSL経由で接続することができる午前

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

UPDATEを。そして、コード

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 

を以下しかし、コマンドラインのmysqlクライアントは、AES256を使用するのに対し、私は生産に根を使用することはできません、とJDBCはAES128を使用していますなぜ私は疑問に思います。

アップデート2私は、クライアントの完全な認証を要求し、[email protected]ためuser表にX509ssl_typeを変更した後、私は、VIC用として根に同じ動作を取得 - JDBC経由でログインすることができません。

Update3と私はGRANT文でREQUIRE SSL代わりのREQUIRE X509を使用している場合 は、コードが動作します。 X509を動作させることは可能ですか?

+0

。 –

+0

自己署名X.509証明書を使用する方法については、私の答えを参照してください http://stackoverflow.com/questions/11509751/how-to-connect-to-mysql-with-x509-using-jdbc –

答えて

0

私はREQUIRE SSLを使用して解決しました。誰かがX509をJDBCで動作させる方法を知っていれば、この情報は高く評価されます。

+0

を参照してください。 MySQL/MariaDB JDBC接続を使用します。 – sehrope

0

私は、クライアントがREQUIRES SSLのみで構成されているときにクライアント証明書のプロパティを指定しなくても接続できます。

3

最近、自己署名証明書のサポートがMariaDB JDBCドライバに追加されました(これはMySQLへの接続でも機能します)。最新バージョン(これを書いている時点では1.1.3)では、実行時にサーバー証明書を直接指定できるため、事前にキーストアを構成したり証明書をインポートしたりする必要はありません。

設定する2つのプロパティは、useSSLserverSslCertです。ここで参照して接続する方法の完全な実施例について

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