MySQL 5.7 InnoDB Tablespace Encryption

举报
eric0435 发表于 2023/05/10 10:00:54 2023/05/10
【摘要】 InnoDB Tablespace EncryptionInnoDB支持对存储file-per-table表空间中的InnoDB表中的数据进行加密。该特性为物理表空间数据文件提供静态加密。InnoDB表空间加密使用两层加密密钥架构,由主加密密钥和表空间密钥组成。当一个InnoDB表被加密时,表空间密钥被加密并存储在表空间头中。当应用程序或经过认证的用户想要访问加密的表空间数据时,InnoDB...

InnoDB Tablespace Encryption

InnoDB支持对存储file-per-table表空间中的InnoDB表中的数据进行加密。该特性为物理表空间数据文件提供静态加密。

InnoDB表空间加密使用两层加密密钥架构,由主加密密钥和表空间密钥组成。当一个InnoDB表被加密时,表空间密钥被加密并存储在表空间头中。当应用程序或经过认证的用户想要访问加密的表空间数据时,InnoDB使用一个主加密密钥来解密表空间密钥。表空间密钥的解密版本永远不会改变,但主加密密钥可以根据需要改变。此操作称为主键旋转。

InnoDB表空间加密特性依赖于keyring插件进行主加密密钥管理。

所有MySQL版本都提供了keyring_file插件,该插件将主加密密钥数据存储在keyring_file_data配置选项指定的位置的keyring文件中。

非企业版MySQL中的InnoDB表空间加密特性使用keyring_file插件进行加密密钥管理,这并不是一个符合法规的解决方案。安全标准,如PCI,FIPS和其他要求使用密钥管理系统来保护、管理和保护密钥库或硬件安全模块(hsm)中的加密密钥。

MySQL企业版提供了keyring_okv插件,其中包括一个KMIP客户端(KMIP 1.1),它与Oracle密钥库(OKV)一起工作,提供加密密钥管理。当InnoDB表空间加密使用OKV进行加密密钥管理时,该特性被称为“MySQL企业”透明数据加密(TDE)。

一个安全、健壮的加密密钥管理解决方案(如OKV)对于安全性和符合各种安全标准至关重要。在其他好处中,使用密钥库可确保密钥安全存储,永远不会丢失,并且只有授权的密钥管理员知道。密钥库还维护加密密钥历史记录

InnoDB表空间加密支持AES (Advanced encryption Standard)块加密算法。它采用ECB (Electronic Codebook)块加密方式对表空间密钥进行加密CBC (Cipher Block chainaining)块加密方式,用于数据加密

InnoDB表空间加密前提条件

必须安装和配置keyring插件(keyring_file插件或keyring_okv插件)。Keyring插件安装在启动时使用--early-plugin-load选项执行。提前加载可以确保插件在InnoDB存储引擎初始化之前可用。

一次只能启用一个keyring插件。不支持启用多个密匙环插件。

一旦在MySQL实例中创建了加密表,在创建加密表时加载的keyring插件必须在InnoDB初始化之前使用--early-plugin-load选项继续加载。如果不这样做,会导致启动和恢复InnoDB时出现错误。

启用加密模块

mysql> INSTALL PLUGIN keyring_file soname 'keyring_file.so';
Query OK, 0 rows affected (0.09 sec)

创建密钥文件目录

[mysql@localhost ~]$ mkdir -p /mysqldata/mysql/mysql-keyring/
[mysql@localhost ~]$ chown -R mysql:mysql /mysqldata/mysql/mysql-keyring/
[mysql@localhost ~]$ chmod -R 775 /mysqldata/mysql/mysql-keyring/

设置加密key存放路径

mysql> set global keyring_file_data='/mysqldata/mysql/mysql-keyring/keyring';
Query OK, 0 rows affected (0.00 sec)

永久启用设置
上诉两个步骤都是临时的,重启服务都会失效,我们把配置写到配置文件里,确保重启服务后也能生效

[mysqld]
early-plugin-load=keyring_file.so
keyring_file_data=/mysqldata/mysql/mysql-keyring/keyring

查看key的存放路径

mysql> show global variables like '%keyring_file_data%';
+-------------------+----------------------------------------+
| Variable_name     | Value                                  |
+-------------------+----------------------------------------+
| keyring_file_data | /mysqldata/mysql/mysql-keyring/keyring |
+-------------------+----------------------------------------+
1 row in set (0.02 sec)

要验证keyring插件是否处于活动状态,请使用SHOW PLUGINS语句或查询INFORMATION_SCHEMA.PLUGINS表。例如:

mysql> show plugins;
+----------------------------+----------+--------------------+-----------------+---------+
| Name                       | Status   | Type               | Library         | License |
+----------------------------+----------+--------------------+-----------------+---------+
| keyring_file               | ACTIVE   | KEYRING            | keyring_file.so | GPL     |
| binlog                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| mysql_native_password      | ACTIVE   | AUTHENTICATION     | NULL            | GPL     |
| sha256_password            | ACTIVE   | AUTHENTICATION     | NULL            | GPL     |
| CSV                        | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| MEMORY                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| InnoDB                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| INNODB_TRX                 | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_LOCKS               | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_LOCK_WAITS          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP                 | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP_RESET           | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMPMEM              | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMPMEM_RESET        | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP_PER_INDEX       | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_CMP_PER_INDEX_RESET | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_BUFFER_PAGE         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_BUFFER_PAGE_LRU     | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_BUFFER_POOL_STATS   | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_TEMP_TABLE_INFO     | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_METRICS             | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_DEFAULT_STOPWORD | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_DELETED          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_BEING_DELETED    | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_CONFIG           | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_INDEX_CACHE      | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_FT_INDEX_TABLE      | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_TABLES          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_TABLESTATS      | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_INDEXES         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_COLUMNS         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_FIELDS          | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_FOREIGN         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_FOREIGN_COLS    | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_TABLESPACES     | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_DATAFILES       | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| INNODB_SYS_VIRTUAL         | ACTIVE   | INFORMATION SCHEMA | NULL            | GPL     |
| MyISAM                     | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| MRG_MYISAM                 | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| PERFORMANCE_SCHEMA         | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| ARCHIVE                    | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| BLACKHOLE                  | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| FEDERATED                  | DISABLED | STORAGE ENGINE     | NULL            | GPL     |
| partition                  | ACTIVE   | STORAGE ENGINE     | NULL            | GPL     |
| ngram                      | ACTIVE   | FTPARSER           | NULL            | GPL     |
+----------------------------+----------+--------------------+-----------------+---------+

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.00 sec)

必须启用innodb_file_per_table选项(默认值)。InnoDB表空间加密只支持每表一个文件的表空间。或者,您可以指定TABLESPACE='innodb_file_per_table'选项,用于创建加密表或修改现有表以启用加密。

mysql> show variables like '%innodb_file_per_table%';
+-----------------------+-------+
| Variable_name         | Value |
+-----------------------+-------+
| innodb_file_per_table | ON    |
+-----------------------+-------+
1 row in set (0.01 sec)

在对生产数据使用InnoDB表空间加密特性之前,请确保已采取措施防止丢失主加密密钥。如果主加密密钥丢失,则无法恢复加密表空间文件中存储的数据。如果您正在使用keyring_file插件,建议您在创建第一个加密表之后以及主密钥旋转前后立即创建keyring文件的备份。keyring文件位置由keyring_file_data配置选项定义。如果您正在使用keyring_okv插件,请确保您已经执行了必要的keyring_okv插件和Oracle密钥库(OKV)配置。

开启和关闭InnoDB表空间加密

要为一个新的InnoDB表启用加密,在create table语句中指定encryption选项。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION='Y';
Query OK, 0 rows affected (0.01 sec)

要对现有的InnoDB表启用加密,请在alter table语句中指定encryption选项。

mysql> alter table abc encryption='y';
Query OK, 1 row affected (0.04 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> show create table abc;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                            |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| abc   | CREATE TABLE `abc` (
  `a` int(11) NOT NULL,
  PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ENCRYPTION='y' |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

使用alter table设置encryption ='N'来禁用InnoDB表的加密功能

mysql> alter table abc encryption='n';
Query OK, 1 row affected (0.02 sec)
Records: 1  Duplicates: 0  Warnings: 0

mysql> show create table abc;
+-------+-------------------------------------------------------------------------------------------------------------------------+
| Table | Create Table                                                                                                            |
+-------+-------------------------------------------------------------------------------------------------------------------------+
| abc   | CREATE TABLE `abc` (
  `a` int(11) NOT NULL,
  PRIMARY KEY (`a`)
) ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 ENCRYPTION='n' |
+-------+-------------------------------------------------------------------------------------------------------------------------+
1 row in set (0.00 sec)

InnoDB表空间加密和主密钥轮换
主加密密钥应该定期轮换,只要您怀疑密钥可能已被泄露。

主密钥轮换是一个原子的实例级操作。每次轮换主加密密钥时,MySQL实例中的所有表空间密钥都将重新加密并保存回各自的表空间头中。作为原子操作,一旦启动轮换操作,所有表空间密钥都必须重新加密成功。如果主密钥轮换因服务器故障而中断,InnoDB将在服务器重启时前滚该操作。

轮换主加密密钥只会更改主加密密钥并重新加密表空间密钥。它不解密或重新加密相关的表空间数据

轮换主加密密钥,执行以下命令:

[root@localhost ~]# cd /mysqldata/mysql/mysql-keyring/
[root@localhost mysql-keyring]# ll
total 4
-rw-r-----. 1 mysql mysql 155 Mar  3 17:20 keyring

mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;
Query OK, 0 rows affected (0.00 sec)

[root@localhost mysql-keyring]# ll
total 4
-rw-r-----. 1 mysql mysql 283 Mar 10 15:58 keyring

alter instance rotate innodb master key支持并发DML。但是,它不能与create table ... encryption或alter table ... encryption操作一起并发执行,采用锁来防止这些语句并发执行时可能产生的冲突。如果一个冲突的语句正在运行,那么它必须在另一个语句运行之前完成。

InnoDB表空间加密与恢复
ALTER INSTANCE ROTATE INNODB MASTER KEY语句仅在主数据库和从数据库所运行的MySQL版本支持表空间加密特性的复制环境中被支持。

成功的ALTER INSTANCE ROTATE INNODB MASTER KEY语句被写入二进制日志,用于在slave上复制。

如果一个ALTER INSTANCE ROTATE INNODB MASTER KEY语句失败,它不会被记录到二进制日志中,也不会被复制到slave上。

如果keyring插件安装在主节点上而从节点没有安装,复制ALTER INSTANCE ROTATE INNODB MASTER KEY操作失败。

如果keyring_file插件同时安装在主服务器和从服务器上,但是从服务器上没有keyring文件,假设keyring文件数据没有缓存在内存中,复制的ALTER INSTANCE ROTATE INNODB MASTER KEY语句将在从服务器上创建keyring文件。如果可用的话,ALTER INSTANCE INNODB MASTER KEY使用缓存在内存中的keyring文件数据。

识别使用InnoDB表空间加密的表
当在CREATE TABLE或ALTER TABLE语句中指定了ENCRYPTION选项时,它将记录在INFORMATION_SCHEMA.TABLES的CREATE_OPTIONS字段中。可以查询该字段以识别MySQL实例中的加密表。

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES
    -> WHERE CREATE_OPTIONS LIKE '%ENCRYPTION="Y"%';
+--------------+------------+-------------------------------------------------------+
| TABLE_SCHEMA | TABLE_NAME | CREATE_OPTIONS                                        |
+--------------+------------+-------------------------------------------------------+
| test         | t1         | ENCRYPTION="Y"                                        |
| test         | ts02       | row_format=COMPRESSED KEY_BLOCK_SIZE=4 ENCRYPTION="Y" |
| test         | ts03       | COMPRESSION="zlib" ENCRYPTION="Y"                     |
+--------------+------------+-------------------------------------------------------+
3 rows in set (0.42 sec)

InnoDB表空间加密使用说明
a.如果服务器在正常运行期间退出或停止,建议使用之前配置的相同加密设置重新启动服务器。

b.第一个主加密密钥是在对第一个新表或现有表进行加密时生成的。

c.主密钥轮换会重新加密表空间密钥,但不会改变表空间密钥本身。要更改表空间密钥,必须使用alter table tbl_name encryption禁用并重新启用表加密,这是一个ALGORITHM=COPY操作来重建表。

d.Keyring_file插件使用说明
如果keyring文件为空或缺失,第一次执行ALTER INSTANCE ROTATE INNODB MASTER KEY将创建一个主加密密钥。

卸载keyring_file插件不会删除现有的keyring文件。

建议不要将keyring文件与表空间数据文件放在同一个目录下。keyring文件的位置由keyring_file_data选项指定。

在运行时修改keyring_file_data选项或使用新的keyring_file_data设置重新启动服务器可能导致以前加密的表不可访问,从而导致数据丢失。

InnoDB表空间加密限制
.系统目前只支持AES (Advanced Encryption Standard)加密算法。InnoDB表空间加密使用ECB (Electronic Codebook)块加密方式对表空间密钥进行加密,使用CBC (Cipher block Chaining)块加密方式对数据进行加密。

.修改表的ENCRYPTION属性是一个ALGORITHM=COPY操作。不支持ALGORITHM=INPLACE。

.InnoDB表空间加密只支持存储在file-per-table表空间中的InnoDB表。存储在其他InnoDB表空间类型中的表不支持加密,包括普通表空间、系统表空间、undo log表空间和临时表空间。

.不能将加密表从file-per-table表空间移动或复制到不支持的InnoDB表空间类型。

.表空间加密只适用于表空间中的数据。重做日志、undo日志或二进制日志中的数据不加密。

.目前不支持直接从keyring_file插件迁移到keyring_okv插件,反之亦然。更改密匙环插件需要解密表,卸载当前的密匙环插件,安装和配置其他密匙环插件,并重新加密表。

【版权声明】本文为华为云社区用户原创内容,转载时必须标注文章的来源(华为云社区)、文章链接、文章作者等基本信息, 否则作者和本社区有权追究责任。如果您发现本社区中有涉嫌抄袭的内容,欢迎发送邮件进行举报,并提供相关证据,一经查实,本社区将立刻删除涉嫌侵权内容,举报邮箱: cloudbbs@huaweicloud.com
  • 点赞
  • 收藏
  • 关注作者

评论(0

0/1000
抱歉,系统识别当前为高风险访问,暂不支持该操作

全部回复

上滑加载中

设置昵称

在此一键设置昵称,即可参与社区互动!

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。

*长度不超过10个汉字或20个英文字符,设置后3个月内不可修改。