当前位置: 首页 > article >正文

【昌哥IT课堂】MySQL8.0新特性之binlog加密与解密

MySQL BINLOG加密与解密

BINLOG加密:

从8.0.14开始,MySQL提供了对binlog的加密功能,默认情况下,binlog是没有加密的,加密需要使用keyring插件或者组件:

以下内容在CentOS 7.9/MySQL 8.0.34版本中进行验证:

安装keyring_file插件

社区版只支持keyring_file插件,企业版本支持更多的加密方式,这里以社区版本作为案例来讲解:

配置文件修改:

在配置文件中添加以下内容

cat /etc/my.cnf

[mysqld]

early-plugin-load=keyring_file.so

keyring_file_data=/var/lib/mysql-keyring/keyring

重新MySQL数据库:

systemctl restart mysqld

实例重启后,会在/var/lib/mysql-keyring/keyring这个目录生成一个数据文件

查看keyring文件存储的目录:

mysql> show  variables  like  '%keyring%';

+--------------------+--------------------------------+

| Variable_name      | Value         |

+--------------------+--------------------------------+

| keyring_file_data  | /var/lib/mysql-keyring/keyring |

| keyring_operations | ON             |

+--------------------+--------------------------------+

2 rows in set (0.01 sec)

查看keyring_file插件的状态:

mysql> select plugin_name,plugin_status from information_schema.plugins where plugin_name like 'keyring%';

+--------------+---------------+

| plugin_name  | plugin_status |

+--------------+---------------+

| keyring_file | ACTIVE        |

+--------------+---------------+

1 row in set (0.04 sec)

以上只是安装了keyring插件,要实现binlog日志加密,还需要开启系统参数。

在没有修改配置之前,binlog日志还是未加密的,如下:

mysql> show binary logs;

+---------------+-----------+-----------+

| Log_name      | File_size | Encrypted |

+---------------+-----------+-----------+

| binlog.000002 |       180 | No      |

| binlog.000003 |       201 | No      |

+---------------+-----------+-----------+

2 rows in set (0.02 sec)

开启BINLOG加密功能:

binlog的加密通过一个系统变量binlog_encryption控制:

set global binlog_encryption=ON;

或者

set persist binlog_encryption=ON;

binlog_encryption参数:

在此服务器上为二进制日志文件和中继日志文件启用加密。默认值为OFF。ON为二进制日志文件中继日志文件设置加密。要启用加密,服务器上不需要启用二进制日志记录,因此可以在没有二进制日志的副本上加密中继日志文件。要使用加密,必须安装并配置密钥环插件以提供MySQL服务器的密钥环服务

在启用二进制日志加密的情况下首次启动服务器时,在初始化二进制日志和中继日志之前会生成一个新的二进制日志加密密钥。该密钥用于为每个二进制日志文件(如果服务器启用了二进制日志记录)和中继日志文件(如果服务器有复制通道)加密一个文件密码,并使用从文件密码生成的进一步密钥来加密文件中的数据。中继日志文件为所有通道加密,包括组复制应用程序通道和在激活加密后创建的新通道。二进制日志索引文件和中继日志索引文件永远不会被加密。

开启后查看日志:

mysql> show binary logs;

+---------------+-----------+-----------+

| Log_name      | File_size | Encrypted |

+---------------+-----------+-----------+

| binlog.000002 |       180 | No      |

| binlog.000003 |       201 | No      |

| binlog.000004 |       713 | Yes      |

+---------------+-----------+-----------+

3 rows in set (0.00 sec)

可以看到是加密了的binlog:(binlog.000004)

删除binlog二进制日志加密功能:

mysql> set  global binlog_encryption=off;

Query OK, 0 rows affected (0.02 sec)

mysql> show binary logs;

+---------------+-----------+-----------+

| Log_name      | File_size | Encrypted |

+---------------+-----------+-----------+

| binlog.000002 |       180 | No        |

| binlog.000003 |       201 | No        |

| binlog.000004 |       713 | Yes       |

| binlog.000005 |       157 | No        |

+---------------+-----------+-----------+

5 rows in set (0.00 sec)

这时会重新切换一个新的二进制日志文件(binlog.000005),这个日志文件没有加密。

以上操作,官方文档说明如下:

如果在服务器运行时激活加密,则会在此时生成一个新的二进制日志加密密钥。例外情况是,如果以前在服务器上激活了加密并且然后禁用了加密,则再次使用以前使用的二进制日志加密密钥。二进制日志文件和中继日志文件会立即进行轮换,并使用此二进制日志加密密钥加密新文件和所有后续的二进制日志文件和中继日志文件的文件密码。服务器上仍存在的现有二进制日志文件和中继日志文件不会自动加密,但如果不再需要它们,可以清除它们。

如果通过将binlog_encryption系统变量更改为OFF来停用加密,二进制日志文件和中继日志文件将立即进行轮换,并且所有后续记录都将是未加密的先前加密的文件不会自动解密,但服务器仍然能够读取它们。

用户与授权:
在服务器运行时,需要BINLOG_ENCRYPTION_ADMIN特权(或已弃用的SUPER特权)来激活或停用加密。组复制应用程序通道不包括在中继日志轮换请求中,因此在正常使用中,直到它们的日志轮换后,这些通道的未加密记录才会开始。

BINLOG日志解密:

当二进制日志文件已加密时,mysqlbinlog无法直接读取它们,但可以使用--read-from-remote-server选项从服务器中读取它们从MySQL 8.0.14开始,如果尝试直接读取加密的二进制日志文件,mysqlbinlog会返回适当的错误,但较旧版本的mysqlbinlog根本不会将文件识别为二进制日志文件。如果使用mysqlbinlog备份加密的二进制日志文件,请注意,使用mysqlbinlog生成的文件副本以未加密格式存储。

没有加密的二进制日志是可以通过mysqlbinlog解析成文本文件的,如下:

[root@mysql-8034 mysql-keyring]# mysqlbinlog --no-defaults --base64-output=decode-rows -v -v /var/lib/mysql/binlog.000003

# The proper term is pseudo_replica_mode, but we use this compatibility alias

# to make the statement usable on server versions 8.0.24 and older.

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

# at 4

#241229 15:45:30 server id 1  end_log_pos 126 CRC32 0x00befe71 Start: binlog v 4, server v 8.0.34 created 241229 15:45:30 at startup

ROLLBACK/*!*/;

# at 126

#241229 15:45:31 server id 1  end_log_pos 157 CRC32 0x59bb747d Previous-GTIDs

# [empty]

# at 157

#241229 15:48:15 server id 1  end_log_pos 201 CRC32 0xa459416a Rotate to binlog.000004  pos: 4

SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;

DELIMITER ;

# End of log file

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

加密后的二进制日志是无法通过mysqlbinlog解析成文本文件,如下:

[root@mysql-8034 mysql-keyring]# mysqlbinlog --no-defaults --base64-output=decode-rows -v -v /var/lib/mysql/binlog.000004

# The proper term is pseudo_replica_mode, but we use this compatibility alias

# to make the statement usable on server versions 8.0.24 and older.

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

ERROR: Reading encrypted log files directly is not supported.

SET @@SESSION.GTID_NEXT= 'AUTOMATIC' /* added by mysqlbinlog */ /*!*/;

DELIMITER ;

# End of log file

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

以上有一个报错,如下:

ERROR: Reading encrypted log files directly is not supported.

当二进制日志文件已加密时,mysqlbinlog无法直接读取它们,但可以使用--read-from-remote-server选项从服务器中读取它们:

[root@mysql-8034 mysql-keyring]# mysqlbinlog -uroot -p'Shukuinfo123.' --socket=/var/lib/mysql/mysql.sock --read-from-remote-server  binlog.000004  --skip-gtids

mysqlbinlog: [Warning] Using a password on the command line interface can be insecure.

# The proper term is pseudo_replica_mode, but we use this compatibility alias

# to make the statement usable on server versions 8.0.24 and older.

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=1*/;

/*!50003 SET @OLD_COMPLETION_TYPE=@@COMPLETION_TYPE,COMPLETION_TYPE=0*/;

DELIMITER /*!*/;

# at 4

#241229 15:48:15 server id 1  end_log_pos 126 CRC32 0x6c79a876 Start: binlog v 4, server v 8.0.34 created 241229 15:48:15

BINLOG '

v/5wZw8BAAAAegAAAH4AAAAAAAQAOC4wLjM0AAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAA

AAAAAAAAAAAAAAAAAAAAAAAAEwANAAgAAAAABAAEAAAAYgAEGggAAAAICAgCAAAACgoKKioAEjQA

CigAAXaoeWw=

'/*!*/;

/*!50616 SET @@SESSION.GTID_NEXT='AUTOMATIC'*//*!*/;

# at 126

# at 157

#241229 15:48:42 server id 1  end_log_pos 201 CRC32 0xfb5aa2a3 Rotate to binlog.000005  pos: 4

DELIMITER ;

# End of log file

/*!50003 SET COMPLETION_TYPE=@OLD_COMPLETION_TYPE*/;

/*!50530 SET @@SESSION.PSEUDO_SLAVE_MODE=0*/;

以是上通过--read-from-remote-server参数,连接到MySQL服务器后,请求服务器的密钥完成了binlog 加密文件的解密

查看当前使用的KEY_ID的值:

mysql> select * from performance_schema.keyring_keys;

+------------------------------------------------------------+-----------+----------------+

| KEY_ID                                                     | KEY_OWNER | BACKEND_KEY_ID |

+------------------------------------------------------------+-----------+----------------+

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803_1 |           |                |

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803   |           |                |

+------------------------------------------------------------+-----------+----------------+

2 rows in set (0.01 sec)

总结:

通过加密binlog日志,就可以防止BINLOG日志被未经授权的查看,可以防止用户数据泄密。

所以,如果没有源数据库实例的帐号和密码,即使拿到了binlog日志,也无法查看binlog数据中的数据

安装或卸载密钥环函数:

以上只安装keyring插件,与keyring更多的细节,在没有安装相关的工具时,是无法查看的,官方在社区版本也提供了查看keyring相关的函数,用来创建和查看keyring。

密钥环函数使密钥环密钥管理操作变得可能,但必须安装`keyring_udf`插件,因为没有它,这些函数无法正常工作。尝试在没有`keyring_udf`插件的情况下使用这些函数会导致错误。

为了让服务器能够使用,插件库文件必须位于MySQL插件目录中(由`plugin_dir`系统变量指定的目录)。如有必要,在服务器启动时通过设置`plugin_dir`的值来配置插件目录位置。

插件库文件的基本名称是`keyring_udf`。文件名后缀因平台而异(例如,Unix和类Unix系统为`.so`,Windows为`.dll`)。

安装插件前,需要确保在插件目录中有keyring_udf.so这个文件:

mysql> select @@plugin_dir;

+--------------------------+

| @@plugin_dir             |

+--------------------------+

| /usr/lib64/mysql/plugin/ |

+--------------------------+

1 row in set (0.00 sec)

mysql> system ls /usr/lib64/mysql/plugin/keyring_udf.so

/usr/lib64/mysql/plugin/keyring_udf.so

要安装`keyring_udf`插件和密钥环函数,请使用`INSTALL PLUGIN`和`CREATE FUNCTION`语句,根据需要调整您平台的后缀(例如`.so`):

在MySQL服务器上安装配置步骤如下:

INSTALL PLUGIN  keyring_udf SONAME  'keyring_udf.so';

CREATE FUNCTION keyring_key_generate RETURNS INTEGER SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_fetch RETURNS STRING SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_length_fetch RETURNS INTEGER SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_type_fetch RETURNS INTEGER SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_store RETURNS INTEGER SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_remove RETURNS INTEGER SONAME 'keyring_udf.so';

用户授权:

用户必须具有全局的EXECUTE权限才能使用任何密钥环函数。否则,将会出现错误:

ERROR 1123(HY000):无法初始化函数'keyring_key_generate';用户无权执行此函数。用户需要具有EXECUTE权限。

要授予用户全局的EXECUTE权限,请使用以下语句:

GRANT EXECUTE ON *.* TO user;

创建密钥案例:

要创建一个新的随机密钥并将其存储在密钥环中,请调用keyring_key_generate(),向其传递密钥的ID,以及密钥类型(加密方法)和以字节为单位的长度。以下调用创建一个名为MyKey的2048位DSA加密密钥:

mysql> SELECT keyring_key_generate('MyKey', 'DSA', 256);

+-------------------------------------------+

| keyring_key_generate('MyKey', 'DSA', 256) |

+-------------------------------------------+

| 1 |

+-------------------------------------------+

返回值1表示成功。如果无法创建密钥,则返回值为NULL并出现错误。可能的原因之一是底层密钥环插件不支持指定的密钥类型和密钥长度组合;

以上创建的密钥可以在系统表中查看,如下图:

mysql> select * from performance_schema.keyring_keys;

+------------------------------------------------------------+----------------+----------------+

| KEY_ID   | KEY_OWNER     | BACKEND_KEY_ID |

+------------------------------------------------------------+----------------+----------------+

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803   |          |  |

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803_1 |   |          |

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803_1 | root@localhost |  |

| MyKey                                                  | root@localhost   |

+------------------------------------------------------------+----------------+----------------+

5 rows in set (0.00 sec)

为了能够检查返回类型,无论是否发生错误,使用SELECT ... INTO @var_name并测试变量值:

mysql> SELECT keyring_key_generate('', '', -1) INTO @x;

ERROR 3188 (HY000): Function 'keyring_key_generate' failed because

underlying keyring service returned an error. Please check if a

keyring plugin is installed and that provided arguments are valid

for the keyring you are using.

mysql> SELECT @x;

+------+

| @x |

+------+

| NULL |

+------+

mysql> SELECT keyring_key_generate('x', 'AES', 16) INTO @x;

mysql> SELECT @x;

+------+

| @x |

+------+

| 1 |

+------+

这种技术也适用于其他密钥环函数,对于失败会返回一个值和一个错误的情况。

通过密钥名查看密钥的类型和长度:

传递给keyring_key_generate()的ID提供了一种在后续函数调用中引用密钥的方式。例如,使用密钥ID作为字符串检索其类型,或者作为整数检索其字节长度:

mysql> SELECT keyring_key_type_fetch('MyKey');

+---------------------------------+

| keyring_key_type_fetch('MyKey') |

+---------------------------------+

| DSA |

+---------------------------------+

mysql> SELECT keyring_key_length_fetch('MyKey');

+-----------------------------------+

| keyring_key_length_fetch('MyKey') |

+-----------------------------------+

| 256 |

+-----------------------------------+

查看密钥值:

要检索密钥值,请将密钥ID传递给keyring_key_fetch()。以下示例使用HEX()显示密钥值,因为它可能包含不可打印字符。示例还使用了一个简短的密钥,但请注意,更长的密钥提供更好的安全性:

mysql> SELECT HEX(keyring_key_fetch('MyKey'))\G;

*************************** 1. row ***************************

HEX(keyring_key_fetch('MyKey')): 4D988DF509376E477159BE244F9E1E35E657FAA4C5E445F3352B8A28C3572223FD222A7631A7B93BBF2CDEE31A36D4C574DCF6D5694030CEF660651545308A9332BF8AF58DE9839E2037612FAB9ACAE0D5EBD00AD901A2980EAA57F6343FAB1647EFBA86CB59D592CC8FD2F00062AA59341A82ACD85AF7995B3ED56214B65762B69C0904768D91BB221059047912A672A43B15E68EB1C33759C13F69291457B8D182A7108DFAAB810AFCC18292A2D639E324D5A5B1D54FDB3C2B8BD47EC64B5157A97A5F69E4F811A8D958A2D2BF048CF02096FE1072E7FF54D8D7AC72BACBC3AB4CECED4F4729D133FDB39EBACACA388621F1E9C47691C33AACEC93FFA3E818

1 row in set (0.06 sec)

ERROR:

No query specified

删除密钥:

要删除一个密钥,请将密钥ID传递给keyring_key_remove():

```sql

mysql> SELECT keyring_key_remove('MyKey');

+-----------------------------+

| keyring_key_remove('MyKey') |

+-----------------------------+

| 1 |

+-----------------------------+

删除操作后,再查看,密钥已删除了

mysql> SELECT keyring_key_length_fetch('MyKey');

+-----------------------------------+

| keyring_key_length_fetch('MyKey') |

+-----------------------------------+

|                              NULL |

+-----------------------------------+

1 row in set (0.00 sec)

mysql> select * from performance_schema.keyring_keys;

+------------------------------------------------------------------+-----------+----------------+

| KEY_ID                                                           | KEY_OWNER | BACKEND_KEY_ID |

+------------------------------------------------------------------+-----------+----------------+

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803         |           |                |

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803_last_pu |           |                |

| MySQLReplicationKey_d4849815-a556-11ef-8e3d-000c291a9803_4       |           |                |

+------------------------------------------------------------------+-----------+----------------+

3 rows in set (0.00 sec)


http://www.kler.cn/a/470198.html

相关文章:

  • pytorch中nn.Conv2d详解及参数设置原则
  • 数据传送类指令
  • Vue3 + Vite + Electron + Ts 项目快速创建
  • 进程间通讯
  • 【C语言程序设计——选择结构程序设计】求阶跃函数的值(头歌实践教学平台习题)【合集】
  • Unity中 Xlua使用整理(一)
  • 力扣leetcode 77 - 组合 C语言解法 递归+回溯
  • 用 HTML5 Canvas 和 JavaScript 实现流星雨特效
  • ENSP综合实验(中小型网络)
  • 解决电脑开机PcaSvc.dll出错丢失条目:PcaWallpaperAppDetect最新方法
  • 物联网:七天构建一个闭环的物联网DEMO
  • 【Golang 面试题】每日 3 题(二十)
  • Java基础 注解
  • C#版OpenCv常用函数大全
  • 手写RPC笔记
  • [Qt] 万字详解 | 常用控件 | Button | Label | LCD | ProgressBar
  • Redis(三)单线程架构介绍
  • QT:控件属性及常用控件(2)-----按钮类控件及显示类控件
  • Rtemis解题过程
  • 基于人脸识别和 MySQL 的考勤管理系统实现
  • 庐山派K230学习日记5 UART
  • LabVIEW软件侵权分析与应对
  • element组件el-select、el-tree-select有值,不渲染lable
  • GitLab创建用户,设置访问SSH Key
  • 数造科技荣获 2024 年“年度数据资源创新开发企业”
  • 软件体系结构与设计模式