mysql ssl 连接配置与Java连接配置全教程

开篇

由于最近工作中有涉及到为mysql配置ssl连接的需求,而且客户的生产环境是windows系统的,所以小编在自己本地安装了mysql,查阅了很多资料,踩了无数坑,终于实现了基本的ssl配置。以下是本人融合很多博客和自己的总结写出的教程,而且博客的最下方的附录中,还会有相关的工具或教程的参考链接。如果有不足之处,敬请批评指正!

开发环境

  • 操作系统:win10
  • Mysql: 5.6.45
  • OpenSSL: Win64OpenSSL_Light-1_1_0L
  • jdk: 1.8
  • Springboot: 2.0.5.RELEASE

正文

安装OpenSSL

OpenSSL是用来创建 SSL 证书和私钥的工具。这里,我根据我自己的系统,选择了版本为Win64OpenSSL_Light-1_1_0L的OpenSSL下载并安装。下载安装教程见附录。

开启远程连接支持

一般配置ssl,都是为了能够在远程连接时,对数据进行加密传输。mysql默认是不支持远程连接的,需要我们手动开启。

use mysql;
update user set host = '%' where user = 'root';
FLUSH PRIVILEGES;

这里将主机名称设置为“%”,即匹配所有的ip,而且指定的登陆账号是root,也就是说对root账号开通远程连接支持。我们可以查看修改后的结果。

select host,user,ssl_type from mysql.user where user ='root';

在这里插入图片描述
可以看到,root账号除了支持本地登陆之外,还支持远程登陆。ssl_type这个字段,我们后面会说到。
另外,还需要开放3306端口。参考链接见附录。

查看是否支持SSL

SHOW VARIABLES LIKE 'have_ssl';

在这里插入图片描述
当 have_ssl 为 YES 时, 表示此时 MySQL 服务已经支持ssl了。如果是 DESABLE, 则需要在启动 MySQL 服务时, 使能 ssl功能。

创建SSL证书和私钥

创建存放证书和私钥的目录

目录可以在任何路径下创建,小编为了方便,将目录创建在mysql配置文件my.ini的同级目录下。

select @@datadir;

运行这个sql,可以看到mysql的数据目录,它的上一级目录,就是配置文件my.ini所在的目录。我的配置文件所在目录:C:\ProgramData\MySQL\MySQL Server 5.6。在这个目录下创建cert目录,用于存放证书和私钥。

生成证书和私钥

在配置文件目录下,进入命令行,使用OpenSSL命令,生成一个CA私钥ca-key.pem。

openssl genrsa 2048 > cert/ca-key.pem

使用私钥生成一个CA证书ca-cert.pem,过期时间为10年

openssl req -sha1 -new -x509 -nodes -days 3650 -key ./cert/ca-key.pem > cert/ca-cert.pem

如下,命令执行后,需要你依次输入国家,地区,城市,组织,组织单位,域名和邮箱。这些信息一般都可以不填,直接回车即可。但是如果你想验证证书的有效性,这里的域名,即common name,填写0.0.0.0,表示匹配网络中的所有主机。在这里插入图片描述
生成服务端的密钥server-key.pem和申请服务端证书的请求文件server-req.pem。

openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout cert/server-key.pem > cert/server-req.pem

如下,执行后,依然要你输入相关的信息,其他信息都可以为空,直接回车即可,这里的域名,即common name,要填写你的有效的域名,或者直接填写你的本地ip,否者,可能造成证书无法被验证的局面。在这里插入图片描述
将生成的服务端私钥server-key.pem,转化为RSA的格式

openssl rsa -in cert/server-key.pem -out cert/server-key.pem

使用上面生成的服务端请求文件server-req.pem、CA证书ca-cert.pem、CA私钥ca-key.pem,生成服务端的证书server-cert.pem。

openssl x509 -sha1 -req -in cert/server-req.pem -days 3650 -CA cert/ca-cert.pem -CAkey cert/ca-key.pem -set_serial 01 > cert/server-cert.pem

生成客户端的密钥client-key.pem和申请客户端证书的请求文件client-req.pem。

openssl req -sha1 -newkey rsa:2048 -days 3650 -nodes -keyout cert/client-key.pem > cert/client-req.pem

同样的,命令执行后,根据提示,域名,即common name这一项,填写你的本机ip,其他的直接为空,回车即可。请注意,服务端和客户端的common name这一项必须一致,而且不能与CA证书的common name相同,否则会导致证书验证失败!
将生成的客户端私钥client-key.pem,转化为RSA格式。

openssl rsa -in cert/client-key.pem -out cert/client-key.pem

使用上面生成的客户端请求文件client-req.pem、CA证书ca-cert.pem、CA私钥ca-key.pem,生成客户端的证书client-cert.pem。

openssl x509 -sha1 -req -in cert/client-req.pem -days 3650 -CA cert/ca-cert.pem -CAkey cert/ca-key.pem -set_serial 01 > cert/client-cert.pem

校验CA证书ca-cert.pem、服务端证书server-cert.pem、客户端证书client-cert.pem。

openssl verify -CAfile cert/ca-cert.pem cert/server-cert.pem cert/client-cert.pem

出现如下字眼,说明证书和私钥成功生成。
在这里插入图片描述
生成的文件如下:
在这里插入图片描述

mysql的SSL开启与证书配置

修改配置文件my.ini,在[mysqld] 配置域下,配置CA证书、服务端证书和服务端密钥地址,并配置MySQL 服务可以接收来自所有 ip 地址的客户端。

ssl-ca=C:/ProgramData/MySQL/MySQL Server 5.6/cert/ca-cert.pem
ssl-cert=C:/ProgramData/MySQL/MySQL Server 5.6/cert/server-cert.pem
ssl-key=C:/ProgramData/MySQL/MySQL Server 5.6/cert/server-key.pem
bind-address = 0.0.0.0

配置root账号使用ssl登陆,这里的密码需要正确填写你当前的root账号密码,否则配置不生效。

GRANT ALL PRIVILEGES ON *.* TO 'root'@'%' IDENTIFIED BY '123456' REQUIRE SSL;
 FLUSH PRIVILEGES;

查看是否修改成功。

select host,user,ssl_type from mysql.user where user ='root';

root账号对应的一个host为“%”,并且ssl_type为"ANY",说明root账号已经支持ssl的远程登陆了。
在这里插入图片描述
重启mysql服务,使配置生效。

本地ssl登陆

使用命令行本地登陆(需要携带CA证书、客户端证书、客户端密钥路径等信息),当然,直接普通登陆也行,因为从上面sql的运行结果可以看出,同时支持本地普通登陆,但是远程登陆必须使用ssl。

mysql --ssl-ca="C:/ProgramData/MySQL/MySQL Server 5.6/cert/ca-cert.pem" --ssl-cert="C:/ProgramData/MySQL/MySQL Server 5.6/cert/client-cert.pem" --ssl-key="C:/ProgramData/MySQL/MySQL Server 5.6/cert/client-key.pem"  -u root -p

登陆成功后,执行命令:

\s

可以看到如下字眼,说明ssl配置成功,而且使用的算法是DHE-RSA-AES256-SHA。
在这里插入图片描述
这时候执行:

show variables like '%ssl%' ;

可以看到,已经支持ssl登陆了,并且还可以看到CA证书和服务端证书、密钥的相关信息。
在这里插入图片描述

远程ssl登陆

使用Navicat尝试远程登陆成功。
在这里插入图片描述
在这里插入图片描述

Java ssl连接配置

生成truststore.jks和keystore.jks

定位到证书的目录,在命令行中,使用CA证书ca-cert.pem,生成truststore.jks,这里的密码我使用123456。

keytool -import -noprompt -file ca-cert.pem -keystore truststore.jks -storepass 123456

使用客户端私钥client-key.pem,将客户端证书client-cert.pem,转化为P12格式,这里的密码我使用相同的123456。

openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -out keystore.p12 -passout pass:123456

使用生成的keystore.p12,生成keystore.jks,这里的密码需要保持一致。

keytool -importkeystore -srckeystore keystore.p12 -srcstoretype PKCS12 -destkeystore keystore.jks -srcstorepass 123456 -deststorepass 123456

出现如下提示,则说明密钥库已经导入成功。
在这里插入图片描述

Springboot项目配置ssl证书连接mysql

小编创建了用来测试ssl连接的简单的Springboot项目,已经上传到了github。如果需要获取,请点击附录中的链接。
在项目根目录下,创建config目录,存放truststore.jks和keystore.jks文件,如下:
在这里插入图片描述
新建配置类Params,设置truststore.jks和keystore.jks路径和密码信息

package com.hejianlin.ssl_jdbc_demo.config;

import lombok.Data;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.stereotype.Component;

@Component
@ConfigurationProperties("params")
@Data
public class Params {
    public String trustStorePath="config/truststore.jks";
    public String trustStorePassword="123456";
    public String keyStorePath = "config/keystore.jks";
    public String keyStorePassword = "123456";
    public String defaultType = "JKS";
}

在启动类中,注入Params,并通过@PostConstruct注解,使用Springboot启动时,自动将ssl证书相关配置,注入到系统变量中。

package com.hejianlin.ssl_jdbc_demo;

import com.hejianlin.ssl_jdbc_demo.config.Params;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.boot.SpringApplication;
import org.springframework.boot.autoconfigure.SpringBootApplication;

import javax.annotation.PostConstruct;
import java.io.File;

@SpringBootApplication(scanBasePackages = {"com.hejianlin.ssl_jdbc_demo"})
public class SslJdbcApplication {

	@Autowired
	Params params;

	public static void main(String[] args) {
		SpringApplication.run(SslJdbcApplication.class, args);
	}

	@PostConstruct
	void postConstruct(){
		File trustStoreFilePath = new File(params.trustStorePath);
		String tsp = trustStoreFilePath.getAbsolutePath();
		System.setProperty("javax.net.ssl.trustStore", tsp);
		System.setProperty("javax.net.ssl.trustStorePassword", params.trustStorePassword);
		System.setProperty("javax.net.ssl.keyStoreType", params.defaultType);
		File keyStoreFilePath = new File(params.keyStorePath);
		String ksp = keyStoreFilePath.getAbsolutePath();
		System.setProperty("Security.KeyStore.Location", ksp);
		System.setProperty("Security.KeyStore.Password", params.keyStorePassword);
	}
}

新建Springboot测试类,通过简单的jdbc,测试mysql的ssl链接是否成功,这里的表是我随便创建的一个表。

@RunWith(SpringJUnit4ClassRunner.class)
@SpringBootTest(classes = SslJdbcApplication.class)
public class JdbcTest {



    @Test
    public void  test(){
        Connection conn=null;
        Statement sta=null;
        try {
            Class.forName("com.mysql.jdbc.Driver");
            String url="jdbc:mysql://192.168.31.89:3306/test?verifyServerCertificate=true&useSSL=true&requireSSL=true";
            String username="root";
            String password="123456";
            conn= DriverManager.getConnection(url, username, password);
            sta=conn.createStatement();
            String sql="INSERT into a (id,sid,type) value (38,6,'dds')";
            int row=sta.executeUpdate(sql);
            System.out.println("增加行数:"+row);
        } catch (ClassNotFoundException e) {
            e.printStackTrace();
        } catch (SQLException e) {
            e.printStackTrace();
        } finally {
            if(sta!=null){
                try {
                    sta.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
            if(conn!=null){
                try {
                    conn.close();
                } catch (SQLException e) {
                    e.printStackTrace();
                }
            }
        }
    }

}

查看结果,看到行数增加了,说明ssl连接成功。
在这里插入图片描述

附录

windows下载安装OpenSSL
mysql使用SSL链接
windows开放指定端口
pem证书转化为jks格式
Springboot加载ssl证书
测试ssl连接的demo项目

  • 6
    点赞
  • 3
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值