JDBC如何通过SSL方式连接MySQL
作者:不会画画的画师
文章介绍了如何配置MySQL以支持SSL连接,并通过JDBC进行安全连接,主要内容包括查看MySQL SSL支持、创建SSL连接用户、配置用户是否强制使用SSL、JDBC配置导入证书以及使用Go编写一个简单的HTTP文件服务器来提供SSL证书
环境说明
MySQL 版本
- MySQL 5.7.26
pom.xml
<dependency> <groupId>mysql</groupId> <artifactId>mysql-connector-java</artifactId> <version>8.0.18</version> </dependency>
JDK版本
- JDK 1.8
MySQL配置SSL
查看MySQL是否支持SSL连接
- 查看MySQL是否支持SSL
SHOW VARIABLES LIKE 'have_ssl'
如果hava_ssl
对应的值为YES
则支持SSL
- 查询ssl证书地址
show variables like '%ssl%';
ssl_ca
对应的就是ssl证书名
创建SSL连接用户
- 创建用户
CREATE USER 'ssler'@'%' IDENTIFIED BY '123456'; GRANT ALL ON *.* TO 'ssler'@'%'
- 查看用户是否使用ssl
SELECT ssl_type From mysql.user Where user="ssler"
截图中ssl_type为空字符串,表示该用户不强制要求使用ssl连接。
- 配置用户必须使用ssl连接
ALTER USER 'ssler'@'%' REQUIRE SSL; FLUSH PRIVILEGES
此时再执行
SELECT ssl_type From mysql.user Where user="ssler"
ANY
表示必须使用ssl连接。
JDBC配置
导入证书
- 使用jdk自带的keytool导入mysql的客户端证书到密钥仓库,并生成密钥文件。
- 根据上文查到的ca.pem,将其复制到目标主机上,然后执行下述指令
$ keytool -import -trustcacerts -v -alias Mysql -file ca.pem -keystore "mysql.ks" 输入密钥库口令: 再次输入新口令: 所有者: CN=MySQL_Server_5.7.26_Auto_Generated_CA_Certificate 发布者: CN=MySQL_Server_5.7.26_Auto_Generated_CA_Certificate 序列号: 1 有效期为 Wed Apr 29 16:32:45 CST 2020 至 Sat Apr 27 16:32:45 CST 2030 证书指纹: MD5: 09:E7:41:84:08:B0:70:5F:AC:D6:03:61:CE:F4:50:DE SHA1: 6B:EE:FE:B4:74:89:A3:88:6C:49:22:44:6D:FB:88:DE:18:6A:7A:F6 SHA256: 83:DD:8F:83:71:08:1D:36:D6:C0:2B:23:D2:E9:DC:84:0E:D6:ED:9A:E5:85:DF:7C:7C:52:33:9A:D7:83:0F:29 签名算法名称: SHA256withRSA 主体公共密钥算法: 2048 位 RSA 密钥 版本: 3 扩展: #1: ObjectId: 2.5.29.19 Criticality=false BasicConstraints:[ CA:true PathLen:2147483647 ] 是否信任此证书? [否]: y 证书已添加到密钥库中 [正在存储mysql.ks]
通过指令验证证书是否导入:
$ keytool -list -keystore mysql.ks 输入密钥库口令: 密钥库类型: jks 密钥库提供方: SUN 您的密钥库包含 1 个条目 mysql, 2020-6-9, trustedCertEntry, 证书指纹 (SHA1): 6B:EE:FE:B4:74:89:A3:88:6C:49:22:44:6D:FB:88:DE:18:6A:7A:F6
将证书放在目标服务器上
在密钥仓库文件生成的文件夹下,配置http服务器。
此处使用go写一个http文件服务器:
package main import "net/http" func main() { http.Handle("/", http.FileServer(http.Dir("."))) http.ListenAndServe(":9999", nil) }
将编译后的go程序放在与mysql.ks同一目录下,并启动即可
编写JDBC代码
public class JDBCMySQL { public static void main(String[] args) { Connection connection = null; String urlWithCe = "jdbc:mysql://192.168.254.82:13306/cloud?" + "useSSL=true&trustCertificateKeyStorePassword=123456&" + "trustCertificateKeyStoreUrl=http://localhost:9999/mysql.ks&" + "allowMultiQueries=true&" + "useUnicode&characterEncoding=UTF-8&" + "verifyServerCertificate=false&requireSSL=true"; try { Class.forName("com.mysql.cj.jdbc.Driver"); connection = DriverManager.getConnection(urlWithCe, "ssler", "123456"); PreparedStatement preparedStatement = connection.prepareStatement("select * from " + "cm_user"); System.out.println(preparedStatement.executeQuery().first()); } catch (Exception exception) { exception.printStackTrace(); } } }
trustCertificateKeyStorePassword=123456
为密钥仓库的密码,在生成密钥仓库文件时配置;trustCertificateKeyStoreUrl=http://localhost:9999/mysql.ks
为证书放置在http服务器后的地址
总结
以上为个人经验,希望能给大家一个参考,也希望大家多多支持脚本之家。