Featured image of post OpenSSL创建SSL自签名证书用于Mysql的TLS验证, 在Springboot的JDBC中使用

OpenSSL创建SSL自签名证书用于Mysql的TLS验证, 在Springboot的JDBC中使用

本文含有: Docker+Mysql 下创建SSL的自签证书, 在JDBC上使用, CA私钥, CA证书, RSA私钥, RSA证书的生成, 最后校验证书

环境: Docker + Mysql5.7

证书主要有下面这几部分组层

证书名称说明
ca.pemCA 证书;用于验证数字证书的可信度
ca-key.pemCA 私钥: 用于对服务器证书进行签名
server-cert.pem、server-key.pem服务端数字证书和私钥;作为服务端身份
client-vert.pem、client-key.pem客户端数字证书和私钥;作为客户端身份

生成证书方法 1

这种方式是最快的, 无须过多配置就可以使用, 但是有效期是 10 年

# 进入mysql容器
docker exec -it ID /bin/bash

# Docker生成证书
/bin/mysql_ssl_rsa_setup   --datadir=/var/lib/mysql

如果你的 Mysql 不是装在 Docker 里的, 可以使用下面方式创建

# Linux 版本
/usr/bin/mysql_ssl_rsa_setup --datadir=/var/lib/mysql

打开 /etc/my.cnf 文件, 添加

ssl-ca = /var/lib/mysql/ca.pem

ssl-cert = /var/lib/mysql/server-cert.pem

ssl-key = /var/lib/mysql/server-key.pem

查看 SSL 情况

show global variables like '%ssl%';

2024-04-18-ssl_1 第二种查看 SSL

show global status like '%ssl%';

2024-04-18-ssl_2

生成证书方法 2

这里提醒下 Country Name 该如何写

根: 可以为空, 也可以自己写个证书颁发机构 (MyCompany Root CA) *_服务器: 填写域名/IP 地址(_.134333.xyz), 不能为空! 不然就会报错(The certificate's CN name does not match the passed value. 0x800B010F(CERT_E_CN_NO_MATCH))

客户端: 可以为空

Country Name (2 letter code) [AU]:cn 国家名(2个字母的代号)

State or Province Name (full name) [Some-State]:cq 省

Locality Name (eg, city) []:cq 市

Organization Name (eg, company) [Internet Widgits Pty Ltd]:gs 公司名

Organizational Unit Name (eg, section) []:gs  组织或部门名

Common Name (eg, YOUR name) []:doris_ca  域名或自己名字(ca证书不要用跟服务端证书或者客户端证书一个common name 会报错!)

Email Address []:   邮箱地址(不填直接回车)

A challenge password []:123456 密码

An optional company name []:gs  公司名

第一步: 创建 CA 私钥和 CA 证书

# 生成一个 CA 私钥
openssl genrsa 2048 > ca-key.pem

# 通过CA私钥生成数字证书
openssl req -new -x509 -nodes -days 36500 -key ca-key.pem -out ca.pem

第二步: 创建服务器的 RSA 私钥和证书

# 创建服务器的私钥和请求证书
# Country Name 一定要填写连接数据库的域名/IP地址
openssl req -newkey rsa:2048 -days 36500 -nodes -keyout server-key.pem -out server-req.pem

# 将私钥转换为RSA私钥文件格式
openssl rsa -in server-key.pem -out server-key.pem

# 用CA证书生成一个服务器的数字证书
openssl x509 -req -in server-req.pem -days 36500 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem

第三步: 创建客户端的 RSA 私钥和证书

# 创建客户端的RSA私钥和数字证书
openssl req -newkey rsa:2048 -days 36500 -nodes -keyout client-key.pem -out client-req.pem

# 将生成的私钥转换为RAS私钥文件格式
openssl rsa -in client-key.pem -out client-key.pem

# 用CA证书来生成一个客户端的数字证书
openssl x509 -req -in client-req.pem -days 36500 -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem

校验证书

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

记得重启 Mysql 哦!

Mysql 其他设置

ssl-ca = /var/lib/mysql/ca.pem

ssl-cert = /var/lib/mysql/server-cert.pem

ssl-key = /var/lib/mysql/server-key.pem

# 强制客户端使用 SSL 连接
require_secure_transport=ON

强制某个用户使用 SSL

ALTER USER 'test'@'%' REQUIRE SSL;

FLUSH PRIVILEGES;

JDBC

首先, 在 JDBC 中是不能直接使用 .pem 的, 需要先转换成 JKS 证书.

  • 第一步: 创建 PKCS12 证书
    • 客户端证书 ( client-cert.pem) 和 客户端证书 ( client-key.pem) 密钥转换为 PKCS12 文件
  • 第二步: 将 PKCS12 转换为 JKS
    • client-keystore.p12 转换为 keystore.jks ,
  • 第三步: 创建 Truststore 信任库
    • ca.pem 转换为 truststore.jks , 就可以用于验证服务器证书
# 第一步: 创建 P12 证书
openssl pkcs12 -export -in client-cert.pem -inkey client-key.pem -passout pass:123456 -out client-keystore.p12

# keystore 证书
keytool -importkeystore -srckeystore client-keystore.p12 -srcstoretype pkcs12 -srcstorepass 123456 -destkeystore keystore.jks -deststoretype pkcs12 -deststorepass 123456

# Truststore 证书
keytool -importcert -file ca.pem -keystore truststore.jks -storepass 123456

证书你可以放在 /resources/mysql_ssl 目录下

ssl:
  cert:
    #path: file:E:/Code/ssl
    path: classpath:mysql_ssl/
  config: true&
    verifyServerCertificate=true&
    requireSSL=true&
    clientCertificateKeyStoreUrl=${ssl.cert.path}/keystore.jks&
    clientCertificateKeyStorePassword=123456&
    trustCertificateKeyStoreUrl=${ssl.cert.path}/truststore.jks&
    trustCertificateKeyStorePassword=123456

spring:
  datasource:
    url: jdbc:mysql://127.0.0.1:3306/eezd_sys?
      serverTimezone=Asia/Shanghai&
      useUnicode=true&
      characterEncoding=utf-8&
      zeroDateTimeBehavior=convertToNull&
      allowPublicKeyRetrieval=true&
      tinyInt1isBit=true&
      useSSL=${ssl.config}
    username: root
    password: root

参考文章: https://blog.csdn.net/weixin_42911645/article/details/127070812 https://blog.csdn.net/qq_36763236/article/details/134693564 https://stackoverflow.com/questions/52317708/mysql-ssl-spring-boot-2 https://roopindersingh.com/programming/converting-pem-certificates-and-private-keys-to-jks/

Licensed under CC BY-NC-SA 4.0
本博客已稳定运行
发表了53篇文章 · 总计28.17k字
使用 Hugo 构建
主题 StackJimmy 设计