微信公众号搜"智元新知"关注
微信扫一扫可直接关注哦!

java – MySQL JDBC over SSL问题

如何让MySQL JDBC通过SSL工作(使用X509证书验证)?

我有自己创建的证书,如MysqL手册中所述,使用SSL进行安全连接,具体来说:

# 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

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测试时,我得到auth失败:用户’vic’@’localhost’的访问被拒绝(使用密码: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

更新如果我使用’root’用户而不是’vic’,我可以通过JDBC连接SSL.然后是代码

    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在root用户表的root用户表中将ssl_type更改为X509后,请求客户端的完全身份验证,我获得了与root相同的行为 – 无法通过JDBC登录.

UPDATE3如果我在GRANT语句中使用REQUIRE SSL而不是REQUIRE X509,则代码可以正常工作.是否可以使X509工作?

解决方法:

最近,MariaDB JDBC驱动程序(也可用于连接MysqL)支持自签名证书.最新版本(编写本文时为1.1.3)还允许您在运行时直接指定服务器证书,这样您就不需要事先配置密钥库或导入证书.

要设置的两个属性是useSSL和serveRSSlCert.后者可以是证书本身(String值),也可以是包含证书的文件的路径(完整路径或类路径相对):

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

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐