爱可生 DBA 团队成员,善于故障剖析、性能优化,个人博客:https://www.jianshu.com/u/a95ec11f67a8,欢迎谈论。本文来源:原创投稿爱可生开源社区出品,原创内容未经授权不得随意利用,转载请联系
起初是由于HTTP在传输数据时利用的是明文(虽然说 POST 提交的数据时放在报体里看不到的,但是还是可以通过抓包工具盗取到)是不屈安的,为理解决这一隐患网景公司推出了SSL安全套接字协议层,SSL 是基于 HTTP 之下 TCP 之上的一个协议层,基于 HTTP 标准并对 TCP 传输数据时进行加密,以是 HTTPS 是 HTTP+SSL/TCP的简称。
由于 HTTPS 的推出受到了很多人的欢迎,在 SSL 更新到 3.0 时,IETF 对 SSL3.0 进行了标准化,并添加了少数机制(但是险些和 SSL3.0无差异),标准化后的 IETF 更名为 TLS1.0(Transport Layer Security 安全传输层协议),可以说 TLS 便是 SSL 的新版本 3.1 。
TLS(Transport Layer Security)是更为安全的升级版 SSL。但 SSL 这一术语更为常用,实际上 MySQL 利用的便是 TLS 协议,而不是 SSL 协议。

想弄清楚下面这一大堆文件的浸染是什么吗?那就必须先理解 TLS 握手过程
├── ca-key.pem├── ca.pem├── client-cert.pem├── client-key.pem├── server-cert.pem└── server-key.pem
1.1 TLS 握手过程
TLS 握手的过程,实在便是秘钥交流的过程,这也是全体TLS 加密技能里最繁芜的一个环节,参考一张网上的图如下:
1.2 密钥算法
对称密钥算法:数据加密和解密时利用相同的密钥。
非对称密钥算法:数据加密和解密时利用不同的密钥,一个是公开的公钥,一个是由用户秘密保存的私钥。利用公钥(或私钥)加密的数据只能用相应的私钥(或公钥)才能解密。
与非对称密钥算法比较,对称密钥算法具有打算速率快的优点,常日用于对大量信息进行加密(如对所有报文加密);而非对称密钥算法,一样平常用于数字署名和对较少的信息进行加密。
把稳:SSL/TLS 协议便是利用对称密钥算法进行数据加密,利用非对称密钥算法进行”对称密钥“的加密。其过程为:
上图中,Server端发送了公钥给客户端,私钥自己保存,这是非对称密钥算法中的公钥、私钥对;客户端会创建一个密钥,这个便是对称加密算法中的密钥。然后用 Server 真个公钥对这个密钥加密,发送给 Server 端;Server 端收到客户端发送过来的加密过的密钥,利用自己的私钥进行解密,得到加密前的密钥;接下来传输数据则利用“对称密钥”进加密和解密。这个便是利用非对称密钥算法担保对称密钥本身的安全。
1.3 数字证书-如何担保公钥的真实性?如果有攻击者假造了 Server 真个公钥并发了客户端,客户端会访问到假网站被窃取信息。显然担保客户端收到的 Server 真个公钥是真实的,是担保全体加密连接可靠性的第一道防线。
数字证书由威信机构 CA(Certification Authority) 签发,签发过程为:
用户首先产生自己的密钥对,并将公钥及部分个人身份信息传送给 CA ;CA 核实用户身份(将实行一些必要的步骤,以确信要求确实由用户发送而来);CA 对用户的所有信息(公钥、所有者、有效期...)进行 Hash 打算,得到一个 Hash 值,然后再利用私钥对 Hash 值进行加密得到署名,就得到了数字证书。该证书包含:用户的公钥、所有者、有效期等信息,同时还附有CA的署名信息。数字证书的验证流程:
客户端会利用同样的 Hash 算法获取该数字证书的 Hash 值 H1;常日浏览器和操作系统中集成了 CA 证书(包含 CA 公钥、所有者),客户端取得这个CA证书,利用个中的 CA 公钥解密署名,得到一个 Hash 值 H2 ;比较 H1 和 H2,如果值相同,则数字证书可信。上述签发和验证流程见下图(参考自网络):
如果 CA 证书不在浏览器和操作系统的可信任区,这种 CA 证书常日被称为自署名 CA 证书(MySQL 自动天生的便是自署名证书,详见下文)。要完成数字证书的验证,则必须事先将自署名 CA 证书放到客户端,并在客户端发起连接时指定这个 CA 证书文件;或者事先将自署名 CA 证书导入到客户真个操作系统可信任区,这样在 TLS 握手过程中也能自动获取到这个 CA 证书。
其余:验证证书在 SSL/TLS 协议中不一定是必须的,比如 mysql 客户端只有指定 --ssl-mode=VERIFY_CA 或者 --ssl-mode=VERIFY_IDENTITY 时才验证 CA 证书。如果 --ssl-mode=REQUIRED,则不验证 CA 证书,只哀求 MySQL Server 端发送公钥给客户端,这就无法担保做事端公钥是真实属于 MySQL server 的。详细见下文。
2. MySQL SSL 加密连接2.1 MySQL做事真个配置启动参数:
--ssl:表示 MySQL 做事端许可加密连接,这个启动参数MySQL8.0默认启用系统变量:
require_secure_transport:指定是否哀求客户端利用加密连接。默认值为 OFF,如果 ON,则表示客户端必须利用加密连接,如果客户端关闭 ssl ,则连接会报错。以下参数指定加密连接时利用的证书和密钥文件:
ssl_ca=ca.pemssl_cert=server-cert.pemssl_key=server-key.pem
MySQL8.0 在启动时会自动天生 SSL 证书、密钥文件,以及 RSA 密钥对文件;或者利用 mysql_ssl_rsa_setup 程序天生上述文件。也可以手工天生:
## SSL证书和密钥文件certs├── ca-key.pem├── ca.pem├── client-cert.pem├── client-key.pem├── server-cert.pem└── server-key.pem# Create CA certificate# 创建CA证书(包含CA公钥)和CA私钥openssl genrsa 2048 > ca-key.pemopenssl req -new -x509 -nodes -days 3600 \ -key ca-key.pem -out ca.pem# Create server certificate, remove passphrase, and sign it# server-cert.pem = public key, server-key.pem = private key# 师长西席成做事器公钥、私钥# 利用CA私钥对做事器公钥署名,得到做事器证书 server-cert.pem,证书中包含公钥、所有者、有效期等明文信息,也有经由 CA 私钥加密对公钥、所有者、有效期...加密后的署名openssl req -newkey rsa:2048 -days 3600 \ -nodes -keyout server-key.pem -out server-req.pemopenssl rsa -in server-key.pem -out server-key.pemopenssl x509 -req -in server-req.pem -days 3600 \ -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out server-cert.pem# Create client certificate, remove passphrase, and sign it# client-cert.pem = public key, client-key.pem = private key# 师长西席成客户端公钥、私钥# 利用CA私钥对客户端公钥署名,得到客户端证书 client-cert.pem,一样平常不须要验证客户端身份,这些文件就不须要用到。当然如果要同时验证 MySQL Server 身份和客户端身份,就须要用到这些文件了。openssl req -newkey rsa:2048 -days 3600 \ -nodes -keyout client-key.pem -out client-req.pemopenssl rsa -in client-key.pem -out client-key.pemopenssl x509 -req -in client-req.pem -days 3600 \ -CA ca.pem -CAkey ca-key.pem -set_serial 01 -out client-cert.pem# 查看证书内容openssl x509 -text -in ca.pem# 验证CA证书(“利用CA证书验证数字证书”更恰当?)openssl verify -CAfile ca.pem server-cert.pem# 输出结果:server-cert.pem: OK
2.2 MySQL客户端配置
MySQL 客户端连接 Server 时,通过 --ssl-mode 参数指定:
--ssl-mode=PREFFERED,默认行为,client 端考试测验利用加密进行连接,如果无法构建加密连接,则会退回到未加密的连接--ssl-mode=REQUIRED时,Client 端须要加密连接,如果无法构建连接,则 Client 端将失落败--ssl-mode=DISABLED,Client 端利用未加密的连接--ssl-mode=VERIFY_CA,Client 端须要加密连接,并且还对 CA 证书进行验证--ssl-mode=VERIFY_IDENTITY,Client 端须要加密的连接,并且还针对 CA 证书和其证书中的做事器主机名实行验证把稳:主机名身份验证 VERIFY_IDENTITY 不适用于由做事器自动创建或利用 mysql_ssl_rsa_setup 手动创建的自署名CA证书。
测试如下:
##当指定 --ssl-mode=REQUIRED,仅哀求加密连接,不须要验证 MySQL Server 身份,以是会直接信赖 MySQL Server 发送给客户真个公钥(即 server-cert.pem 数字证书中的明文公钥,忽略个中的数字署名信息)[root@172-16-21-5 /]# /opt/mysql/base/8.0.21/bin/mysql -h172.16.21.4 -P3306 -utest -ptestpass --ssl-mode=REQUIRED -e "select 1"mysql: [Warning] Using a password on the command line interface can be insecure.+---+| 1 |+---+| 1 |+---+##当指定 --ssl-mode=VERIFY_CA,须要验证 CA 证书,由于这个 CA 证书是自签发的,以是不在浏览器和操作系统的可信任区,无法从浏览器和操作系统的可信任区这个公共渠道获取 CA 证书,以是报错:[root@172-16-21-5 /]# /opt/mysql/base/8.0.21/bin/mysql -h172.16.21.4 -P3306 -utest -ptestpass --ssl-mode=VERIFY_CAERROR 2026 (HY000): SSL connection error: CA certificate is required if ssl-mode is VERIFY_CA or VERIFY_IDENTITY##将MySQL做事真个 ca.pem 拷贝到客户端scp ca.pem 172.16.21.5:/tmp/##--ssl-mode=VERIFY_CA,指定须要验证 CA 证书,由于这个 CA 证书是自签发的,以是不在浏览器和操作系统的可信任区,则必须要将 CA 证书拷贝到客户端,并指定 CA 证书文件##TLS 握手过程中,MySQL Server 发送做事器数字证书 server-cert.pem 给客户端,客户端利用 CA 证书中的 CA 公钥解密 server-cert.pem 中的署名,验证通过,才可以正常上岸:[root@localhost ~]# mysql -h10.186.61.173 -P3308 -uhucq -p'1qaz@WSX' \--ssl-ca="/tmp/ca.pem" \--ssl-mode=VERIFY_CA \-e "select 1"+---+| 1 |+---+| 1 |+---+##由于MySQL自动天生的CA证书是自署名证书,而 --ssl-mode=VERIFY_IDENTITY 不适用于由做事器自动创建或利用 mysql_ssl_rsa_setup手动创建的自署名CA证书,纵然指定本地的CA证书文件,连接也会失落败[root@localhost ~]# mysql -h10.186.61.173 -P3308 -uhucq -p'1qaz@WSX' \--ssl-ca="/tmp/ca.pem" \--ssl-mode=VERIFY_IDENTITY \-e "select 1"ERROR 2026 (HY000): SSL connection error: Failed to verify the server certificate via X509 certificate matching functions
2.3 MySQL SSL 连接中的 TLS 握手过程
上述示例已有详细解释,这里再简要总结一下:
客户端发起 ssl 连接要求;MySQL Server 发送数字证书 server-cert.pem 给客户端(server-cert.pem包含:做事器公钥、CA署名信息);客户端利用CA 证书 ca.pem(由于这是 MySQL 自署名的CA证书,无法从操作系统的可信任区获取(压根不在这里边),以是事先必须在客户端本地保存 CA 证书文件)中的 CA 公钥解密 server-cert.pem 中的署名,进行验证;验证通过后,天生对称密钥,利用 server-cert.pem 中的公钥加密“对称密钥”,发送给 MySQL Server;MySQL Server 利用自己保留的私钥 server-key.pem 解密,得到“对称密钥”;接下来传输数据则利用“对称密钥”进加密和解密。如果仅指定 --ssl-mode=REQUIRED,不指定 --ssl-mode=VERIFY_CA 或者 --ssl-mode=VERIFY_IDENTITY,则不须要步骤3。
3. JDBC 如何设置SSL连接首先 MySQL Server 端必须天生 SSL 证书和密钥文件,并且在启动时指定启动参数:--ssl(一样平常将其写到 my.cnf 中)。MySQL8.0 启动时会自动天生SSL 证书和密钥文件,并默认利用 --ssl 参数。
JDBC 关闭 ssl 连接示例:jdbc:mysql://localhost:3306/hucq?useSSL=false
如果 MySQL Server 利用 caching_sha2_password(MySQL8.0默认的认证插件)、sha256_password 认证插件,则还必须指定 AllowPublicKeyRetrieval=True,由于 caching_sha2_password 插件哀求交流密码时必须利用 RSA 公钥加密(在没有利用SSL加密连接的情形下),AllowPublicKeyRetrieval=True 参数浸染是要求 MySQL Server 端发送 RSA 公钥给客户端,如果不要求 RSA 公钥并且又没有指定客户端本地RSA公钥文件(先从 MySQL 做事器上拷贝 RSA 公钥到本地),则连接会报错。该当配置:jdbc:mysql://localhost:3306/hucq?useSSL=false&AllowPublicKeyRetrieval=True
JDBC 开启 SSL 连接,意味着哀求安全连接,则该当开启 CA 证书认证,跟 mysql 客户端一样,须要将 MySQL 的自署名 CA 证书导入到客户端,或者放到 ftp 上,再通过 JDBC 参数指定 CA 证书路径,比较繁芜,请参考官方文档:https://dev.mysql.com/doc/connector-j/8.0/en/connector-j-reference-using-ssl.html
参考资料https://tangyuxian.com/2021/05/19/%E5%90%8E%E7%AB%AF/%E7%AE%97%E6%B3%95/%E7%AE%97%E6%B3%95-TLS-SSL%E6%8F%A1%E6%89%8B%E8%BF%87%E7%A8%8B/https://dev.mysql.com/doc/refman/8.0/en/using-encrypted-connections.html