MySQL表空间加密(TDE) 原创 数据库 2021年10月20日 07:39 夏至未至 3571 当前内容 6347 字,在路上,马上到,马上到 ### 背景概述 在 MySQL 5.7 中,新增功能 `Innodb表空间加密` 以保护静态数据,简称 TDE (Transparent Data Encryption) ,即透明数据加密,此加密支持**每个表的所有文件表空间**,并且**不支持共享表空间**,这种加密技术基于旋转密钥文件而起作用,有两种类型的密钥管理插件可用于密钥管理 1. keyring_file插件 – 在所有MySQL版本中可用。 2. keyring_okv插件 – 在MySQL企业版中可用。 ### 插件支持情况 1. MySQL 5.7.11之后,所有版本包含keyring_file插件 2. MySQL 5.7.12之后,企业版包含keyring_okv插件 3. MySQL 5.7.13之后,所有版本包含key管理的SQL接口(UDF,用户定义函数) ### 密钥介绍 #### 密钥组成 一种两层加密架构,由一个master key (主加密密钥)和多个tablespace key (表空间密钥)组成; ##### 主加密密钥 主密钥用于加密和解密表空间密钥 ##### 表空间密钥 表空间密钥用于加密和解密表空间数据 #### 密钥文件加密 数据库通过 mysql keyring 对独立表空间中的 InnoDB表的数据进行加密,来提升物理文件的安全性。 #### 加密方式 InnoDB 表空间加密支持高级加密标准 (AES) 基于块的加密算法 > Only one keyring plugin should be enabled at a time. Enabling multiple keyring plugins is not supported. 一次只能启用一个密钥环插件。 不支持启用多个密钥环插件。 #### 加密原理图  #### 原理描述 用户可以看到,主密钥存储在数据库外部。表空间键存储在受主键保护的表空间头中。对于加密的表,表空间密钥由主密钥加密并存储在表空间标头中。这里,使用的加密算法是AES,加密模式是块加密模式(CBC)。 在innodb中,页面是使用表空间密钥加密的,并且是在IO层完成的。可以修改页面的时间可能在缓冲区中,然后被刷新。因此,我们避免在页面被修改时对页面数据进行加密,而是在写入磁盘之前先进行加密。加密是由后台页面清理程序线程完成的,该线程指出查询线程不会花费更多的CPU。缓冲池保持解密状态,因为没有访问页面的开销。 ### 局限性 1. 共享/系统表空间(ibdata1)未加密。 2. 二进制,撤消和重做日志未加密。(MySQL 8.0支持重做日志和撤消日志加密)。 3. 高级加密标准(AES)是唯一受支持的加密算法。 4. 无法将加密的表从file_per_table表空间移动或复制到不受支持的innodb表空间。 5. 它仅支持InnoDB Engine。 ### 数据库配置加密插件 以下使用 keyring_file 插件为例,实践配置和表加密、解密过程。 #### 修改配置文件 在mysql配置文件中【mysqld】小结下添加如下内容: plugin_dir=/usr/local/mysql/lib/plugin/ early-plugin-load=keyring_file.so keyring_file_data=/usr/local/mysql/keyring/keyring innodb_file_per_table=1 其中 plugin_dir 来源: ```cpp [root@node1 keyring]# find / -name keyring_file.so /usr/local/mysql/lib/plugin/debug/keyring_file.so /usr/local/mysql/lib/plugin/keyring_file.so ``` #### 添加目录 创建数据库配置文件中涉及到得目录,并修改其属主属组和权限 **注意**:keyring_file_data 里配置的keyring会在启动时自动创建,本步骤中创建到对应目录即可 mkdir -p /usr/local/mysql/keyring chown -R mysql:mysql /usr/local/mysql/keyring/ chmod 750 /usr/local/mysql/keyring/ 重启实例,使配置生效 ```cpp [root@node1 /]# service mysql restart Shutting down MySQL.. SUCCESS! Starting MySQL.. SUCCESS! ``` #### 安装插件 ```cpp mysql> INSTALL PLUGIN keyring_file soname 'keyring_file.so'; Query OK, 0 rows affected, 1 warning (0.01 sec) mysql> ``` #### 卸载插件 UNINSTALL PLUGIN keyring_file; #### 插件检查 查看插件是否启用 ```cpp mysql> show plugins; +----------------------------+----------+--------------------+-----------------+---------+ | Name | Status | Type | Library | License | +----------------------------+----------+--------------------+-----------------+---------+ | keyring_file | ACTIVE | KEYRING | keyring_file.so | GPL | +----------------------------+----------+--------------------+-----------------+---------+ 45 rows in set (0.00 sec) mysql> ``` 或者 ```cpp mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS, PLUGIN_Type,PLUGIN_Library FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring_file'; +--------------+---------------+-------------+-----------------+ | PLUGIN_NAME | PLUGIN_STATUS | PLUGIN_Type | PLUGIN_Library | +--------------+---------------+-------------+-----------------+ | keyring_file | ACTIVE | KEYRING | keyring_file.so | +--------------+---------------+-------------+-----------------+ 1 row in set (0.00 sec) mysql> ``` ### 加密操作 #### 加密表创建 ```cpp mysql> use tde; Database changed mysql> mysql> CREATE TABLE test (t1 INT) ENCRYPTION='Y'; Query OK, 0 rows affected (0.04 sec) mysql> ``` #### 查看加密表 ```cpp mysql> select * from information_schema.tables where create_options like '%ENCRYPTION%="y"%'\G; *************************** 1. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: tde TABLE_NAME: test TABLE_TYPE: BASE TABLE ENGINE: InnoDB VERSION: 10 ROW_FORMAT: Dynamic TABLE_ROWS: 0 AVG_ROW_LENGTH: 0 DATA_LENGTH: 16384 MAX_DATA_LENGTH: 0 INDEX_LENGTH: 0 DATA_FREE: 0 AUTO_INCREMENT: NULL CREATE_TIME: 2021-10-22 17:26:00 UPDATE_TIME: NULL CHECK_TIME: NULL TABLE_COLLATION: latin1_swedish_ci CHECKSUM: NULL CREATE_OPTIONS: ENCRYPTION="Y" TABLE_COMMENT: 1 row in set (0.03 sec) ``` #### 修改表加密 ```cpp mysql> ALTER TABLE test ENCRYPTION='N'; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> mysql> select * from information_schema.tables where create_options like '%ENCRYPTION%="y"%'\G; Empty set (0.05 sec) ERROR: No query specified mysql> mysql> ALTER TABLE test ENCRYPTION='Y'; Query OK, 0 rows affected (0.01 sec) Records: 0 Duplicates: 0 Warnings: 0 mysql> mysql> select * from information_schema.tables where create_options like '%ENCRYPTION%="y"%'\G; *************************** 1. row *************************** TABLE_CATALOG: def TABLE_SCHEMA: tde TABLE_NAME: test TABLE_TYPE: BASE TABLE ENGINE: InnoDB VERSION: 10 ROW_FORMAT: Dynamic TABLE_ROWS: 0 AVG_ROW_LENGTH: 0 DATA_LENGTH: 16384 MAX_DATA_LENGTH: 0 INDEX_LENGTH: 0 DATA_FREE: 0 AUTO_INCREMENT: NULL CREATE_TIME: 2021-10-22 17:27:00 UPDATE_TIME: NULL CHECK_TIME: NULL TABLE_COLLATION: latin1_swedish_ci CHECKSUM: NULL CREATE_OPTIONS: ENCRYPTION="Y" TABLE_COMMENT: 1 row in set (0.03 sec) ``` #### 查看秘钥 ```cpp mysql> show variables like '%keyring%'; +--------------------+----------------------------------+ | Variable_name | Value | +--------------------+----------------------------------+ | keyring_file_data | /usr/local/mysql/keyring/keyring | | keyring_operations | ON | +--------------------+----------------------------------+ 2 rows in set (0.00 sec) mysql> ``` ### keyring管理 #### 定时备份 可以固定时间进行备份,需要还原的时候再拷贝至目标文件 #### 定时更新 为了考虑安全性,当key不安全时,需要进行更新。更新后原先的表依旧可以正常方案,因为更新置灰改变 master encryption key 并重新加密 tablespace keys,不会对表空间重新加密或解密。 更新的方法: ```cpp mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY; Query OK, 0 rows affected (0.00 sec) ``` ### 参考资料 更多详情请参照官网了解 [表空间加密](https://dev.mysql.com/doc/refman/5.7/en/innodb-data-encryption.html "表空间加密") 本文标题: MySQL表空间加密(TDE) 本文作者: 夏至未至 发布时间: 2021年10月20日 07:39 最近更新: 2023年10月17日 14:19 原文链接: 许可协议: 署名-非商业性-禁止演绎 4.0 国际(CC BY-NC-ND 4.0) 请按协议转载并保留原文链接及作者 MySQL表空间加密(1) TDE(1) 下一个 C++设计模式-简单工厂模式 当前文章评论暂未开放,请移步至留言处留言。