MySQL数据库SSL配置和SSL连接测试

本文详细介绍了MySQL服务器的SSL配置方法及各种连接测试场景,包括服务端强制启用SSL、客户端连接配置及Java应用通过SSL连接MySQL的步骤。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

目录

一、MySQL Server和Client多种不同SSL配置情况的连接测试

二、MySQL SSL配置开启的配置流程


环境信息:Centos7 + MySQL 5.7.21

在该环境上进行SSL连接测试。

一、MySQL Server和Client多种不同SSL配置情况的连接测试

MySQL Server 配置:

vi /etc/my.cnf

[mysql]
default-character-set = utf8mb4

[client]
default-character-set = utf8mb4

# ssl_mode = [ DISABLED | PREFERRED(default if not set) | REQUIRED | VERIFY_CA | VERIFY_IDENTITY ]
# ssl_mode 为客户端可选参数,如果客户端连接时指定了则生效的是客户端连接时指定的参数,如果客户端连接未指定则使用服务端的[client]中的配置参数,如果未配置默认为PREFRED。
#   DISABLED: 非SSL连接。
#   PREFERRED: SSL/no-ssl。如果不配置、默认就是该行为。先尝试SSL连接、如果失败则尝试非SSL连接。
#   REQUIRED: SSL连接。仅尝试SSL连接,SSL连接失败则失败、不会尝试非SSL连接。
#   VERIFY_CA: SSL连接,双向认证。校验ca证书、但不校验证书中的server host name。
#   VERIFY_IDENTITY: SSL连接,双向认证。校验ca证书、同时校验证书中的server host name。
#ssl_mode = PREFERRED
ssl_mode = VERIFY_CA

[mysqld]

datadir=/var/lib/mysql
socket=/var/lib/mysql/mysql.sock

validate_password=off

# for ssl enable
# 服务器端配置强制SSL连接、禁止非SSL连接
require_secure_transport = ON
# 下面3个参数如果不配置或者值配置成ca.pem, server-cert.pem, server-key.pem,不加路径,则MySQL默认行为是读取数据目录下的三个文件
ssl-ca=/var/lib/mysql/ssl-cert/ca.pem
ssl-cert=/var/lib/mysql/ssl-cert/server-cert.pem
ssl-key=/var/lib/mysql/ssl-cert/server-key.pem

#for mysqlbinlog enable
server-id=1
log-bin=/var/lib/mysql/mysql-bin
binlog_format=row
expire_logs_days=15
max_binlog_size=500m

#utf8mb4
character-set-client-handshake=false
character-set-server=utf8mb4
collation-server=utf8mb4_unicode_ci
init_connect='SET NAMES utf8mb4'

# for blob input, default value is 4194304 (4M) if not set
#max_allowed_packet = 100M

# for other performance settings
max_connections = 2000
max_connect_errors = 500
back_log = 1000
thread_cache_size = 64
table_open_cache_instances = 500
###show global status like '%open%table%'; Open_tables / Opened_tables 85%~95%
table_open_cache = 10000
table_definition_cache = 2000
innodb_thread_concurrency = 0
max_tmp_tables = 100

## common sql commands
## -- show engine innodb status \G;
## -- show global variables like '%thread%';
## -- show global status like '%thread%';
## -- show global status like '%open%table%';
## -- show variables like '%table%';

# Disablinr symbolic-links is recommended to prevent assorted security risks
symbolic-links=0

log-error=/var/log/mysqld.log
pid-file=/var/run/mysqld/mysqld.pid

编写测试脚本:

vi cmd.sh

#!/bin/sh

# ssl-test-qftools

SQL_SSL="
# check if server start with --ssl:\n
# -- show variables like '%have_ssl%';\n
\n
# check if server force accpet ssl session request ( deny no-ssl requests ):\n
# -- show variables like 'require_secure_transport';\n
\n
# client connected and check current session ssl status:\n
# -- show session status like 'Ssl_cipher';\n
\n
# check ssl configs:\n
# -- show variables like '%ssl%';\n
"
# java keystore.jks generate cmd: keytool -importcert -trustcacerts -file ca.pem -keystore keystore216.jks -storepass 1q2w3e

HOST=192.168.1.216
PORT=3306
USER=root
DIR=./ssl-cert

# for MySQL old Versin
#$SSLOPT=--ssl
#$SSLOPT="--ssl --ssl-verify-server-cert"

# for MySQL new Version
SSLOPT_DISABLED="--ssl-mode=DISABLED"
SSLOPT_PREFERRED="--ssl-mode=PREFERRED"
SSLOPT_REQUIRED="--ssl-mode=REQUIRED"
# ssl && also perform verification against the server CA certificate but no against the server host name in its certificate.
SSLOPT_CA="--ssl-mode=VERIFY_CA"
# ssl && also perform verification against the server CA certificate and (with VERIFY_IDENTITY) against the server host name in its certificate.
SSLOPT_IDENTITY="--ssl-mode=VERIFY_IDENTITY"

CA=$DIR/ca.pem
CERT=$DIR/client-cert.pem
KEY=$DIR/client-key.pem


# 客户端连接时不指定相关参数、由服务器配置决定最终行为
CMD0="mysql -h$HOST -P$PORT -u$USER -p "
# 客户端连接指定配置
# no-ssl
CMD1="mysql -h$HOST -P$PORT -u$USER -p $SSLOPT_DISABLED"
# ssl/no-ssl 先尝试SSL连接、如果失败则尝试非SSL连接
CMD2="mysql -h$HOST -P$PORT -u$USER -p $SSLOPT_PREFERRED"
# ssl单向,SSL连接失败则失败、不会尝试非SSL连接
CMD3="mysql -h$HOST -P$PORT -u$USER -p $SSLOPT_REQUIRED"
# ssl单向、虽然多余传ca证书、客户端证书和秘钥(实际上无需传),实际效果还是单向。MySQL Server my.cnf [client] 中如果配置为 ssl_mode = VERIFY_CA ,连接时客户端如果指定ssl_mode参数则会覆盖,以客户端配置优先
CMD4="mysql -h$HOST -P$PORT -u$USER -p $SSLOPT_REQUIRED --ssl-ca=$CA  --ssl-cert=$CERT --ssl-key=$KEY"
# ssl双向认证,不验证hostname
CMD5="mysql -h$HOST -P$PORT -u$USER -p $SSLOPT_CA --ssl-ca=$CA  --ssl-cert=$CERT --ssl-key=$KEY"
# ssl双向认证 && 验证hostname
CMD6="mysql -h$HOST -P$PORT -u$USER -p $SSLOPT_IDENTITY --ssl-ca=$CA  --ssl-cert=$CERT --ssl-key=$KEY"


if [ ! $# -eq 1 ] || [ "$1" == "-h" ];then
  echo ""
  echo "Please user: $0 {type}"
  echo "  type: 0 | 1 | 2 | 3 | 4 | 5 | 6"
  echo "  type 0 for run: $CMD0"
  echo "  type 1 for run: $CMD1"
  echo "  type 2 for run: $CMD2"
  echo "  type 3 for run: $CMD3"
  echo "  type 4 for run: $CMD4"
  echo "  type 5 for run: $CMD5"
  echo "  type 6 for run: $CMD6"
  echo -e "\n---------------------\n"
  echo "About sql for show ssl infos after mysql connected: "
  echo -e $SQL_SSL
  exit
fi


inputType=$1
if [ -z inputType ];then
  inputType=1
fi

echo "inputType = $inputType"

if [ $inputType -eq 0 ];then
  echo $CMD0
  $CMD0
elif [ $inputType -eq 1 ];then
  echo $CMD1
  $CMD1
elif [ $inputType -eq 2 ];then
  echo $CMD2
  $CMD2
elif [ $inputType -eq 3 ];then
  echo $CMD3
  $CMD3
elif [ $inputType -eq 4 ];then
  echo $CMD4
  $CMD4
elif [ $inputType -eq 5 ];then
  echo $CMD5
  $CMD5
elif [ $inputType -eq 6 ];then
  echo $CMD6
  $CMD6
else
  echo "ERROR: inputType unsupport!"
  exit
fi

从MySQL Server服务器拷贝证书和Key到客户端机器上,然后客户端机器上执行相关测试:
[root@localhost ssl_test]# ls -l
total 4
-rwxr--r-- 1 root root 3165 Apr 25 01:40 cmd.sh
drwxr-xr-x 2 root root   62 Apr 24 21:45 ssl-cert
[root@localhost ssl_test]# ls -l ssl-cert/
total 12
-rw-r--r-- 1 root root 1107 Apr 24 21:45 ca.pem
-rw-r--r-- 1 root root 1107 Apr 24 21:45 client-cert.pem
-rw------- 1 root root 1679 Apr 24 21:45 client-key.pem


SSL连接测试失败的情况:
./cmd.sh 0
./cmd.sh 1
./cmd.sh 6

SSL连接失败的执行详细信息:
[root@localhost ssl_test]# ./cmd.sh 0
inputType = 0
mysql -h192.168.1.216 -P3306 -uroot -p
Enter password: 
ERROR 2026 (HY000): SSL connection error: CA certificate is required if ssl-mode is VERIFY_CA or VERIFY_IDENTITY
[root@localhost ssl_test]# 

[root@localhost ssl_test]# ./cmd.sh 1
inputType = 1
mysql -h192.168.1.216 -P3306 -uroot -p --ssl-mode=DISABLED
Enter password: 
ERROR 3159 (HY000): Connections using insecure transport are prohibited while --require_secure_transport=ON.
[root@localhost ssl_test]# 

[root@localhost ssl_test]# ./cmd.sh 6
inputType = 6
mysql -h192.168.1.216 -P3306 -uroot -p --ssl-mode=VERIFY_IDENTITY --ssl-ca=./ssl-cert/ca.pem --ssl-cert=./ssl-cert/client-cert.pem --ssl-key=./ssl-cert/client-key.pem
Enter password: 
ERROR 2026 (HY000): SSL connection error: SSL certificate validation failure
[root@localhost ssl_test]# 

SSL连接测试成功的情况:
./cmd.sh 2
./cmd.sh 3
./cmd.sh 4
./cmd.sh 5
 

注意:

1)如果 Java demo ssl 方式连接 MySQL 时报错:
Caused by: javax.net.ssl.SSLHandshakeException: No appropriate protocol (protocol is disabled or cipher suites are inappropriate)

SSL握手异常,可能是因为Java高版本默认配置禁用了SSL协议或加密套件。
找到 java 安全配置文件 java.security,修改配置。

查看 Java 版本
java -version

查看 java 路径
whereis java
ls -l /usr/bin/java
ls -l /etc/alternatives/java
find /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64 -name java.security

文件位置在:jre/lib/security/java.security

修改安全配置文件:
vim /usr/lib/jvm/java-1.8.0-openjdk-1.8.0.412.b08-1.el7_9.x86_64/jre/lib/security/java.security


找到配置参数并修改。

修改前:
# Example:
#   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves
    
修改后(取消 TLSv1, TLSv1.1, 禁用配置):
# Example:
#   jdk.tls.disabledAlgorithms=MD5, SSLv3, DSA, RSA keySize < 2048
#jdk.tls.disabledAlgorithms=SSLv3, TLSv1, TLSv1.1, RC4, DES, MD5withRSA, \
#    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
#    include jdk.disabled.namedCurves

jdk.tls.disabledAlgorithms=SSLv3, RC4, DES, MD5withRSA, \
    DH keySize < 1024, EC keySize < 224, 3DES_EDE_CBC, anon, NULL, \
    include jdk.disabled.namedCurves
 

2)如果 Java demo ssl 方式连接 MySQL 时报错:
Caused by: sun.security.validator.ValidatorException: PKIX path building failed: sun.security.provider.certpath.SunCertPathBuilderException: unable to find valid certification path to requested target
这是在JDK8及以上高版本使用中,因为源应用程序不信任目标应用程序的证书,在源应用程序的JVM信任库中找不到该证书或证书链的原因导致的。
需要手动生成证书文件,然后放到jdk对应目录下,重启就行。
生成的证书文件存放位置:jdk\jre\lib\security

或者在Java应用程序中设置 keyStore 和 trustStore:
System.setProperty("javax.net.ssl.keyStore", keyStoreFilePath);
System.setProperty("javax.net.ssl.keyStorePassword", "123456");
System.setProperty("javax.net.ssl.trustStore", trustStoreFilePath);
System.setProperty("javax.net.ssl.trustStorePassword", "123456");


# 将服务器证书导入到 truststore
keytool -import -alias CACert -file ca.pem -keystore truststore

# 将客户端证书和私钥导入到 keystore
keytool -import -alias ClientCert -file client-cert.pem -keystore keystore 
 

MySQL SSL证书的生成方法:

方法1)可以参考:《GBase8a SSL 配置_gbase配置外部访问-CSDN博客

方法2)可以参考本文后面《执行 mysql_ssl_rsa_setup 安装命令》,默认在 mysql bin 目录下带有 mysql_ssl_rsa_setup 执行文件。执行它开始安装 ssl,执行后会生成 ssl 相关秘钥和证书文件。

3)如果报错:Caused by: java.security.cert.CertificateNotYetValidException: NotBefore: Wed Aug 21 20:51:33 CST 2024
说明MySQL客户端和MySQL服务端的时间不同步。

二、MySQL SSL配置开启的配置流程


1. MySQL Server Create SSL/RSA Files 的官方介绍

《4.4.5 mysql_ssl_rsa_setup — Create SSL/RSA Files》
MySQL 8.0:https://dev.mysql.com/doc/refman/8.0/en/mysql-ssl-rsa-setup.html
MySQL 5.7:https://dev.mysql.com/doc/refman/5.7/en/mysql-ssl-rsa-setup.html

2. MySQL Server 配置SSL功能开启的官方介绍

《8.3.1 Configuring MySQL to Use Encrypted Connections》
MySQL 8.0:https://dev.mysql.com/doc/refman/8.0/en/using-encrypted-connections.html
MySQL 5.7:https://dev.mysql.com/doc/refman/5.7/en/using-encrypted-connections.html


3. 我以MySQL配置开启操作步骤示例

1) 先查看MySQL Server的SSL功能是否已开启


mysql> show variables like "%ssl%";
查看 have_openssl、have_ssl 的值是否为 Yes

mysql> show variables like "%ssl%";
+---------------+----------+
| Variable_name | Value    |
+---------------+----------+
| have_openssl  | DISABLED |
| have_ssl      | DISABLED |
| ssl_ca        |          |
| ssl_capath    |          |
| ssl_cert      |          |
| ssl_cipher    |          |
| ssl_crl       |          |
| ssl_crlpath   |          |
| ssl_key       |          |
+---------------+----------+


2) 停止 MySQL 服务


service mysqld stop
service mysqld status

systemctl stop mysqld
systemctl status mysqld


3) 执行 mysql_ssl_rsa_setup 安装命令


默认在 mysql bin 目录下带有 mysql_ssl_rsa_setup 执行文件。执行它开始安装 ssl,执行后会生成 ssl 相关秘钥和证书文件(ca证书和私钥、client证书和私钥、server证书和私钥、private/public公私钥对)、总共8个文件。

注意:如果不是使用 mysql_ssl_rsa_setup 生成、一次执行会生成8个文件。如果是自己使用 openssl 命令生成私钥和证书的话,按需生成就行,如果单向认证,只需要生成ca证书、服务端私钥和服务端证书即可,无需生成客户端证书和私钥。

mkdir -p /var/lib/mysql/ssl-cert
chown -R mysql:mysql /var/lib/mysql/ssl-cert
mysql_ssl_rsa_setup --datadir=/var/lib/mysql/ssl-cert --user=mysql --uid=mysql


执行命令结果如下:
[root@localhost mysql]# mysql_ssl_rsa_setup --datadir=/var/lib/mysql/ssl-cert --user=mysql --uid=mysql
Generating a 2048 bit RSA private key
............+++
............................................+++
writing new private key to 'ca-key.pem'
-----
Generating a 2048 bit RSA private key
....................................+++
..................................................+++
writing new private key to 'server-key.pem'
-----
Generating a 2048 bit RSA private key
.................+++
................+++
writing new private key to 'client-key.pem'
-----
[root@localhost mysql]# 
[root@localhost mysql]# 
[root@localhost mysql]# ls -l ssl-cert/
total 32
-rw------- 1 mysql mysql 1675 Aug 22 17:30 ca-key.pem
-rw-r--r-- 1 mysql mysql 1107 Aug 22 17:30 ca.pem
-rw-r--r-- 1 mysql mysql 1107 Aug 22 17:30 client-cert.pem
-rw------- 1 mysql mysql 1675 Aug 22 17:30 client-key.pem
-rw------- 1 mysql mysql 1679 Aug 22 17:30 private_key.pem
-rw-r--r-- 1 mysql mysql  451 Aug 22 17:30 public_key.pem
-rw-r--r-- 1 mysql mysql 1107 Aug 22 17:30 server-cert.pem
-rw------- 1 mysql mysql 1679 Aug 22 17:30 server-key.pem
[root@localhost mysql]# 

说明:
--datadir 参数指定生成文件的保存路径,如果不单独创建目录、也可以直接指定到 mysql data 目录,注意,保存生成文件的目录,一定要有mysql用户访问的权限,所以,一般都是放在 mysql data 目录下。
--user 和  --uid 参数如果不加,默认为mysql

如果不单独创建目录,直接生成文件放在 msyql data 目录下则可以执行:
mysql_ssl_rsa_setup --datadir=/var/lib/mysql --user=mysql --uid=mysql

也可以执行时不加任何参数,默认以mysql用户执行、生成的文件在的默认路径为 mysql data 目录
mysql_ssl_rsa_setup


4)修改MySQL配置文件my.cnf、设置ssl相关参数


vim /etc/my.cnf

[mysqld]
ssl-ca=/var/lib/mysql/ssl-cert/ca.pem
ssl-cert=/var/lib/mysql/ssl-cert/server-cert.pem
ssl-key=/var/lib/mysql/ssl-cert/server-key.pem


6)启动MySQL

service mysqld start
service mysqld status

systemctl start mysqld
systemctl status mysqld


7)登录MySQL查看ssl相关配置和当前连接的ssl状态的相关命令


mysql> show variables like "%ssl%";   -- server ssl cfg: have_openssl & have_ssl
mysql> \s;   -- current session ssl: SSL
mysql> status;  -- current session ssl: SSL
mysql> show status like '%ssl%';  -- server ssl cfg (ssl variables): Ssl_cipher


8)服务端强制配置指定某个用户必须使用SSL连接

-- 方式1:create user 创建时强制指定使用 SSL 连接
-- drop user frank;
-- for remote login
mysql> create user 'frank'@'%' identified by '1q2w3e' REQUIRE SSL;
mysql> grant all on *.* to 'frank'@'%';
mysql> flush privileges;
mysql> show grants for 'frank'@'%';
mysql> select host, user, ssl_type, ssl_cipher from mysql.user;


-- 方式3:alter user 指定强制使用 SSL 连接
mysql> alter user 'frank'@'%' REQUIRE SSL;
mysql> flush privileges;


-- 如果要取消SSL,则执行
mysql> alter user 'frank'@'%' require none;
mysql> flush privileges;


9)查询MySQL所有用户的ssl配置

mysql> select user, host, ssl_type, ssl_cipher from mysql.user;


10)客户端以SSL方式连接测试

i)命令行访问

mysql -h10.80.93.40 -P3306 -ufrank -p --ssl-mode=REQUIRED --ssl-ca=./ssl-cert/ca.pem  --ssl-cert=./ssl-cert/client-cert.pem --ssl-key=./ssl-cert/client-key.pem
mysql> status;
......
SSL:                    Cipher in use is DHE-RSA-AES256-SHA
......

详细介绍参考官方手册:《8.3.1 Configuring MySQL to Use Encrypted Connections》
https://dev.mysql.com/doc/refman/8.0/en/using-encrypted-connections.html#using-encrypted-connections-client-side-configuration
https://dev.mysql.com/doc/refman/5.7/en/using-encrypted-connections.html#using-encrypted-connections-client-side-configuration

多种MySQL Server服务端的不同配置、以及MySQL CLient客户端的不同传参的连接方式的测试情况,参考本文签名第一部分的介绍(一、MySQL Server不同配置 & MySQL CLient不同连接传参的多种情况测试)


ii)Java 应用访问

官方关于Java JDBC SSL连接的介绍参考:MySQL :: MySQL Connector/J Developer Guide :: 6.9 Connecting Securely Using SSL

服务器身份验证:

MySQL :: MySQL Connector/J Developer Guide :: 6.9.1 Setting up Server Authentication

客户端身份验证:

MySQL :: MySQL Connector/J Developer Guide :: 6.9.2 Setting up Client Authentication

SSL加密连接有单向认证和双向认证的区分,单向认证客户端不需要生成客户端证书、仅服务端配置指定ca证书和服务端证书和服务端私钥即可。双向认证需要生成客户端证书。

具体 Java 客户端连接时,jdbcRUL 需要用到哪些文件(keystore、trustore),由 jdbcURL 的传参决定。

下面加单测试几种情况:

方式a)加密连接、但客户端不使用证书

&useSSL=true&requireSSL=true&verifyServerCertificate=false


方式b)加密连接、且客户端使用证书、设置服务器身份验证(verifyServerCertificate=true 模拟命令行的 VERIFY_CA,用到 trustore)


把服务器端的 ca.pem 证书拷贝到客户端,再执行命令,添加到 truststore 密钥库(执行完会生成一个 truststore 文件):
设置服务器身份验证:导入服务器证书
keytool -importkeystore -alias MySQLCACert -file ca.pem -keystore truststore -storepass 123456

再在 jdbcURL 中指使用 truststore 文件路径和密码:
&useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificateKeyStorePassword=123456&trustCertificateKeyStoreUrl=file:/home/frank/ssl-cert/truststore

注意:
1)trustCertificateKeyStoreUrl 也支持 http 协议,例如:trustCertificateKeyStoreUrl =http://192.168.1.250:8080/truststore
2)trustCertificateKeyStorePassword 和 trustCertificateKeyStoreUrl 也可以不在 jdbcURL 中指定、而直接设置 java 启动参数:
-Djavax.net.ssl.trustStore=/home/frank/ssl-cert/truststore -Djavax.net.ssl.trustStorePassword=123456

也可以在代码中设置:

private void setSysProperties(String target) {
    String keyStorePath = System.getProperty("user.dir") + "/ssl-cert/keystore";
    String trustStorePath = System.getProperty("user.dir") + "/ssl-cert/truststore";
    
    if ("keyStore".equalsIgnoreCase(target) || "all".equalsIgnoreCase(target)) {
        System.setProperty("javax.net.ssl.keyStore", keyStorePath);
        System.setProperty("javax.net.ssl.keyStorePassword", "123456");
    }
    if ("trustSotre".equalsIgnoreCase(target) || "all".equalsIgnoreCase(target)) {
        System.setProperty("javax.net.ssl.trustStore", trustStorePath);
        System.setProperty("javax.net.ssl.trustStorePassword", "123456");
    }
}

private void removeSysProperties() {
    System.getProperties().remove("javax.net.ssl.keyStore");
    System.getProperties().remove("javax.net.ssl.keyStorePassword");
    System.getProperties().remove("javax.net.ssl.trustStore");
    System.getProperties().remove("javax.net.ssl.trustStorePassword");
}

public void connWithSSL2() {
    String url = "jdbc:mysql://192.168.1.40:3306/testdb?useSSL=true&requireSSL=true&verifyServerCertificate=true";
    String user = "test";
    String pwd = "123456";
    Connection conn = null;
    Statement st = null;
    ResultSet rs = null;
    
    setSysProperties("all");
    try {
        Class.forName("com.mysql.jdbc.Driver");
        DriverManager.setLoginTimeout(1);
        conn = DriverManager.getConnection(url, user, pwd);
        st = conn.createStatement();
        rs = st.executeQuery("show status like '%SSL%'");
        while (rs.next()) {
            if (rs.getString(1).startsWith("Ssl_cipher") ||
                    rs.getString(1).startsWith("Ssl_ver")) {
                System.out.println(rs.getString(1) + "-----"
                        + rs.getString(2).substring(0,min(50,rs.getString(2).length())));
            }
        }
    } catch (ClassNotFoundException e) {
        e.printStackTrace();
    } catch (SQLException e) {
        e.printStackTrace();
    } finally {
        removeSysProperties();
        closeResource(conn, st, rs);
    }
}

方式c)加密连接、且客户端使用证书、设置服务器身份验证+客户端身份验证(同时用到 keystore、trustore)

设置服务器身份验证:导入服务器证书、生成 truststore JKS文件:
执行该步骤后会提示输入认证密码,比如输入123456(jdbc连接会用到), 提示是否信任证书:Trust this certificate? [no]:  输入 yes 即可:
keytool -importkeystore -alias MySQLCACert -file ca.pem -keystore truststore -storepass 123456


设置客户端身份验证:将客户端密钥(client-key.pem)和证书文件(client-cert.pem)转换为 PKCS #12 存档:(在数据库服务器端执行命令生成):
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -name "mysqlclient" -passout pass:123456 -out client-keystore.p12


将客户端密钥和证书导入 Java 密钥库、生成 keystore JSK文件:
keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore keystore -deststoretype JKS -deststorepass 123456


jdbcURL:
jdbc:mysql://192.168.1.40:3306/testdb?useSSL=true&requireSSL=true&verifyServerCertificate=true&trustCertificateKeyStoreUrl=file:/home/frank/ssl-cert/truststore&trustCertificateKeyStorePassword=123456&clientCertificateKeyStoreUrl=file:/home/frank/ssl-cert/keystore&clientCertificateKeyStorePassword=123456
 

该方式连接时, trustore 和 keystore 必须同时存在,否则,如果只有 keystore 而没有 trustore 的话,就会报错如下:

Caused by: java.security.NoSuchAlgorithmException: Error constructing implementation (algorithm: Default, provider: SunJSSE, class: sun.security.ssl.SSLContextImpl$DefaultSSLContext)
        at java.security.Provider$Service.newInstance(Provider.java:1617)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:236)
        at sun.security.jca.GetInstance.getInstance(GetInstance.java:164)
        at javax.net.ssl.SSLContext.getInstance(SSLContext.java:156)
        at javax.net.ssl.SSLContext.getDefault(SSLContext.java:96)
        at javax.net.ssl.SSLSocketFactory.getDefault(SSLSocketFactory.java:122)
        at com.mysql.jdbc.ExportControlled.getSSLSocketFactoryDefaultOrConfigured(ExportControlled.java:159)
        at com.mysql.jdbc.ExportControlled.transformSocketToSSLSocket(ExportControlled.java:82)
        ... 20 more
Caused by: java.security.KeyStoreException: problem accessing trust store
        at sun.security.ssl.TrustManagerFactoryImpl.engineInit(TrustManagerFactoryImpl.java:75)
        at javax.net.ssl.TrustManagerFactory.init(TrustManagerFactory.java:250)
        at sun.security.ssl.SSLContextImpl$DefaultManagersHolder.getTrustManagers(SSLContextImpl.java:882)
        at sun.security.ssl.SSLContextImpl$DefaultManagersHolder.<clinit>(SSLContextImpl.java:854)
        at sun.security.ssl.SSLContextImpl$DefaultSSLContext.<init>(SSLContextImpl.java:1027)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
        at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
        at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
        at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
        at java.security.Provider$Service.newInstance(Provider.java:1595)
        ... 27 more
Caused by: java.io.IOException: Keystore was tampered with, or password was incorrect
        at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:785)
        at sun.security.provider.JavaKeyStore$JKS.engineLoad(JavaKeyStore.java:56)
        at sun.security.provider.KeyStoreDelegator.engineLoad(KeyStoreDelegator.java:224)
        at sun.security.provider.JavaKeyStore$DualFormatJKS.engineLoad(JavaKeyStore.java:70)
        at java.security.KeyStore.load(KeyStore.java:1445)
        at sun.security.ssl.TrustStoreManager$TrustAnchorManager.loadKeyStore(TrustStoreManager.java:372)
        at sun.security.ssl.TrustStoreManager$TrustAnchorManager.getTrustedCerts(TrustStoreManager.java:320)
        at sun.security.ssl.TrustStoreManager.getTrustedCerts(TrustStoreManager.java:59)
        at sun.security.ssl.TrustManagerFactoryImpl.engineInit(TrustManagerFactoryImpl.java:51)
        ... 36 more
Caused by: java.security.UnrecoverableKeyException: Password verification failed
        at sun.security.provider.JavaKeyStore.engineLoad(JavaKeyStore.java:783)
        ... 44 more

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包

打赏作者

sunny05296

你的鼓励将是我创作的最大动力

¥1 ¥2 ¥4 ¥6 ¥10 ¥20
扫码支付:¥1
获取中
扫码支付

您的余额不足,请更换扫码支付或充值

打赏作者

实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

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

余额充值