InnoDB支持针对每个表文件表 空间,常规 表空间,mysql系统表空间,重做日志和撤消日志的静态数据加密 。

从MySQL 8.0.16开始,还支持为模式和常规表空间设置加密默认值,这允许DBA控制是否对在这些模式和表空间中创建的表进行加密。

关于静态数据加密
InnoDB使用两层加密密钥体系结构,包括主加密密钥和表空间密钥。对表空间进行加密时,表空间密钥将被加密并存储在表空间标头中。当应用程序或经过身份验证的用户想要访问加密的表空间数据时,请 InnoDB使用主加密密钥来解密表空间密钥。表空间密钥的解密版本永远不会更改,但是可以根据需要更改主加密密钥。此操作称为主键旋转。

静态数据加密功能依赖于密钥环插件进行主加密密钥管理。

所有MySQL版本均提供一个keyring_file 插件,该插件将密钥环数据存储在服务器主机本地的文件中。

MySQL Enterprise Edition提供了其他密钥环插件:

该keyring_encrypted_file插件将密钥环数据存储在服务器主机本地的加密文件中。

该keyring_okv插件包括一个KMIP客户端(KMIP 1.1),该客户端使用KMIP兼容产品作为密钥环存储的后端。受支持的KMIP兼容产品包括集中式密钥管理解决方案,例如Oracle Key Vault,Gemalto KeySecure,Thales Vormetric密钥管理服务器和Fornetix密钥编排。

该keyring_aws插件与Amazon Web Services密钥管理服务(AWS KMS)通信,作为密钥生成的后端,并使用本地文件存储密钥。

警告
在keyring_file和 keyring_encrypted file插件并非意合规性解决方案。PCI,FIPS等安全性标准要求使用密钥管理系统来保护,管理和保护密钥库或硬件安全模块(HSM)中的加密密钥。

安全且强大的加密密钥管理解决方案对于安全性以及对各种安全标准的遵守至关重要。当静态数据加密功能使用集中式密钥管理解决方案时,该功能称为“ MySQL企业透明数据加密(TDE) ”。

静态数据加密功能支持基于高级加密标准(AES)块的加密算法。它使用电子密码簿(ECB)块加密模式进行表空间密钥加密,并使用密码块链接(CBC)块加密模式进行数据加密。

有关静态数据加密功能的常见问题,请参见第A.17节“ MySQL 8.0 FAQ:InnoDB静态数据加密”。

加密先决条件
必须安装和配置密钥环插件。使用early-plugin-load选项在启动时执行Keyring插件安装 。尽早加载可确保插件在InnoDB存储引擎初始化之前可用。有关密钥环插件的安装和配置说明,请参见第6.4.4节“ MySQL密钥环”。

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

重要
在MySQL实例中创建加密表空间后,创建该加密表空间时加载的密钥环插件必须在启动时使用该early-plugin-load 选项继续加载。否则,启动服务器和InnoDB恢复期间会导致错误。

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

mysql> SELECT PLUGIN_NAME, PLUGIN_STATUS
       FROM INFORMATION_SCHEMA.PLUGINS
       WHERE PLUGIN_NAME LIKE 'keyring%';
+--------------+---------------+
| PLUGIN_NAME  | PLUGIN_STATUS |
+--------------+---------------+
| keyring_file | ACTIVE        |
+--------------+---------------+

对生产数据进行加密时,请确保采取措施以防止丢失主加密密钥。如果主加密密钥丢失,则无法恢复存储在加密表空间文件中的数据。如果使用 keyring_file或 keyring_encrypted_file插件,请在创建第一个加密表空间之后,主密钥旋转之前和主密钥旋转之后立即创建密钥环数据文件的备份。的 keyring_file_data 配置选项定义了密钥环数据文件位置keyring_file插件。的 keyring_encrypted_file_data 配置选项定义了密钥环数据文件位置keyring_encrypted_file插件。如果您使用keyring_okv或 keyring_aws插件,请确保您已执行必要的配置。有关说明,请参见 第6.4.4节“ MySQL密钥环”。

定义架构和常规表空间的加密默认值
从MySQL 8.0.16开始, default_table_encryption系统变量定义了模式和常规表空间的默认加密设置。当未明确指定子句时CREATE TABLESPACE, CREATE SCHEMA操作将应用该 default_table_encryption设置ENCRYPTION。

ALTER SCHEMA并且ALTER TABLESPACE操作不应用该 default_table_encryption设置。ENCRYPTION必须明确指定一个子句以更改现有模式或常规表空间的加密。

default_table_encryption 可以为单个客户端连接或使用SET 语法全局设置 该变量 。例如,以下语句全局启用默认模式和表空间加密:

mysql> SET GLOBAL default_table_encryption=ON;
DEFAULT ENCRYPTION在创建或更改架构时, 也可以使用子句来定义架构的默认加密设置,如以下示例所示:

mysql> CREATE SCHEMA test DEFAULT ENCRYPTION = 'Y';
如果DEFAULT ENCRYPTION在创建模式时未指定该子句,则将default_table_encryption应用该 设置。DEFAULT ENCRYPTION必须指定该子句以更改现有模式的默认加密。否则,该架构将保留其当前的加密设置。

默认情况下,表继承在其中创建架构或常规表空间的加密设置。例如,默认情况下,在启用加密的架构中创建的表被加密。此行为使DBA可以通过定义和实施架构和常规表空间加密默认值来控制表加密的使用。

通过启用table_encryption_privilege_check 系统变量来强制执行加密默认设置 。当 table_encryption_privilege_check 启用时,创建或更改架构或一般的表空间与从不同的加密设置时发生特权检查 default_table_encryption设置,或者创建或更改表与加密设置时,从默认模式加密不同。如果 table_encryption_privilege_check 禁用(默认设置),则不会进行特权检查,并且允许前面提到的操作进行警告。

该TABLE_ENCRYPTION_ADMIN 权限需要时覆盖默认的加密设置 table_encryption_privilege_check 启用。DBA可以授予此特权,以使用户能够default_table_encryption在创建或更改模式或常规表空间时偏离 设置,或者在创建或更改表时偏离默认模式加密。创建或更改表时,此特权不允许偏离常规表空间的加密。表必须具有与其所在的常规表空间相同的加密设置。

每表文件表空间加密
从MySQL 8.0.16开始,每表文件表空间继承了在其中创建表的模式的默认加密,除非在ENCRYPTION语句中明确指定了一个子句CREATE TABLE 。在MySQL 8.0.16之前,ENCRYPTION必须指定该 子句以启用加密。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';
要更改现有的每表文件表空间的加密,ENCRYPTION必须指定一个子句。

mysql> ALTER TABLE t1 ENCRYPTION = 'Y';
从MySQL 8.0.16开始,如果table_encryption_privilege_check 启用了变量,则 ENCRYPTION 使用与默认模式加密不同的设置来指定子句需要 TABLE_ENCRYPTION_ADMIN特权。请参阅为模式和常规表空间定义加密默认值。

常规表空间加密
从MySQL 8.0.16开始,该 default_table_encryption变量确定新创建的常规表空间的加密,除非ENCRYPTION在该CREATE TABLESPACE 语句中明确指定了子句。在MySQL 8.0.16之前,ENCRYPTION 必须指定一个子句以启用加密。

mysql> CREATE TABLESPACE ts1 ADD DATAFILE 'ts1.ibd' ENCRYPTION = 'Y' Engine=InnoDB;
要更改现有通用表空间的加密,ENCRYPTION必须指定一个 子句。

mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';
从MySQL 8.0.16开始,如果table_encryption_privilege_check 启用了变量,则 ENCRYPTION 使用设置不同于该default_table_encryption设置的子句 指定该TABLE_ENCRYPTION_ADMIN 特权。请参阅 为模式和常规表空间定义加密默认值。

mysql系统表空间加密
mysql自MySQL 8.0.16起 ,对系统表空间的加密支持已可用。

该mysql系统表空间包含 mysql系统数据库和MySQL数据字典表。默认情况下未加密。要为mysql系统表空间启用加密,请 ENCRYPTION在ALTER TABLESPACE语句中指定表空间名称和选项 。

mysql> ALTER TABLESPACE mysql ENCRYPTION = 'Y';
要禁用mysql系统表空间的加密,请ENCRYPTION = 'N'使用一条 ALTER TABLESPACE语句进行设置。

mysql> ALTER TABLESPACE mysql ENCRYPTION = 'N';
为mysql 系统表空间启用或禁用加密需要CREATE TABLESPACE实例中所有表的特权(CREATE TABLESPACE on .)。

重做日志加密
使用innodb_redo_log_encrypt 配置选项启用重做日志数据加密 。默认情况下,重做日志加密是禁用的。

与表空间数据一样,重做日志数据加密是在将重做日志数据写入磁盘时进行的,而解密是在从磁盘读取重做日志数据时进行的。一旦重做日志数据读入内存,它就处于未加密形式。使用表空间加密密钥对重做日志数据进行加密和解密。

当innodb_redo_log_encrypt启用时,是存在于磁盘加密重做日志页面未被加密,并且新的重做日志页写入以加密形式的磁盘。同样, innodb_redo_log_encrypt禁用此选项后,磁盘上存在的加密重做日志页面将保持加密状态,新的重做日志页面将以未加密形式写入磁盘。

重做日志加密元数据(包括表空间加密密钥)存储在第一个重做日志文件(ib_logfile0)的标头中。如果删除此文件,则重做日志加密将被禁用。

启用重做日志加密后,将无法在没有密钥环插件或加密密钥的情况下正常重启,因为 InnoDB必须能够在启动过程中扫描重做页面,如果重做日志页面已加密,则无法进行。如果没有密钥环插件或加密密钥,则只有在没有重做日志(SRV_FORCE_NO_LOG_REDO)的情况下才能强制启动。请参见 第15.21.2节“强制InnoDB恢复”。

撤消日志加密
使用innodb_undo_log_encrypt 配置选项启用了撤消日志数据加密 。撤消日志加密适用于驻留在撤消表空间中的撤消日志。请参见第15.6.3.4节“撤消表空间”。默认情况下,撤消日志数据加密是禁用的。

与表空间数据一样,将撤消日志数据写入磁盘时会进行撤消日志数据加密,而从磁盘读取撤消日志数据则会发生解密。一旦撤消日志数据读入内存,它就处于未加密形式。撤消日志数据使用表空间加密密钥进行加密和解密。

当innodb_undo_log_encrypt启用时,是存在于磁盘加密撤消日志页面未被加密,并且新的撤销日志页写入以加密形式的磁盘。同样, innodb_undo_log_encrypt禁用此选项后,磁盘上存在的加密撤消日志页将保持加密状态,新的撤消日志页将以未加密形式写入磁盘。

撤消日志加密元数据(包括表空间加密密钥)存储在撤消日志文件的标头中。

注意
禁用撤消日志加密后,服务器将继续要求使用用于加密撤消日志数据的密钥环插件,直到包含加密的撤消日志数据的撤消表空间被截断为止。(仅在撤消表空间被截断时才从撤消表空间中删除加密头。)有关截断撤消表空间的信息,请参见截断撤消表空间。

主密钥轮换
应定期旋转主加密密钥,只要您怀疑密钥已被盗用,就应该对其进行旋转。

主键旋转是原子的,实例级的操作。每次旋转主加密密钥时,MySQL实例中的所有表空间密钥都会重新加密并保存回各自的表空间头中。作为原子操作,一旦启动旋转操作,所有表空间密钥的重新加密都必须成功。如果服务器故障中断了主密钥旋转,则InnoDB在服务器重新启动时将操作向前滚动。有关更多信息,请参见 加密和恢复。

旋转主加密密钥仅会更改主加密密钥并重新加密表空间密钥。它不会解密或重新加密关联的表空间数据。

旋转主加密密钥需要 ENCRYPTION_KEY_ADMIN特权(或不建议使用的SUPER特权)。

要旋转主加密密钥,请运行:

mysql> ALTER INSTANCE ROTATE INNODB MASTER KEY;

ALTER INSTANCE ROTATE INNODB MASTER KEY支持并发DML。但是,它不能与表空间加密操作同时运行,并且会采取锁定措施来防止可能由于并发执行而引起的冲突。如果某个ALTER INSTANCE ROTATE INNODB MASTER KEY操作正在运行,则必须先完成该操作,然后才能进行表空间加密操作,反之亦然。

加密与恢复
如果在加密操作期间发生服务器故障,则在重新启动服务器时将前滚操作。对于常规表空间,将从最后处理的页面在后台线程中恢复加密操作。

如果在主密钥旋转期间发生服务器故障,请 InnoDB在服务器重新启动时继续操作。

必须在存储引擎初始化之前加载密钥环插件,以便在InnoDB初始化和恢复活动访问表空间数据之前,可以从表空间头中检索解密表空间数据页所需的信息。(请参阅 加密先决条件。)

当InnoDB初始化和恢复开始时,主键旋转操作将恢复。由于服务器故障,某些表空间密钥可能已经使用新的主加密密钥进行了加密。InnoDB从每个表空间标头读取加密数据,如果数据指示表空间密钥已使用旧的主加密密钥进行了加密,请InnoDB从密钥环中检索旧密钥并将其用于解密表空间密钥。 InnoDB然后使用新的主加密密钥重新加密表空间密钥,并将重新加密的表空间密钥保存回表空间标头。

导出加密的表空间
仅每个表文件表空间支持表空间导出。

导出加密的表空间时,将 InnoDB生成用于加密表空间密钥的传输密钥。加密的表空间密钥和传输密钥存储在 tablespace_name.cfp 文件中。该文件与加密的表空间文件一起执行导入操作是必需的。导入时, InnoDB使用传输密钥解密tablespace_name.cfp 文件中的表空间密钥 。有关相关信息,请参见 第15.6.1.3节“导入InnoDB表”。

加密和复制
ALTER INSTANCE ROTATE INNODB MASTER KEY仅在主服务器和从服务器运行支持表空间加密的MySQL版本的复制环境中才支持 该语句。

成功的ALTER INSTANCE ROTATE INNODB MASTER KEY语句将写入二进制日志以在从属服务器上复制。

如果一条ALTER INSTANCE ROTATE INNODB MASTER KEY语句失败,则该语句不会记录到二进制日志中,也不会在从属服务器上复制。

ALTER INSTANCE ROTATE INNODB MASTER KEY如果将密钥环插件安装在主服务器上而不是从服务器上,则操作 复制失败。

如果在主服务器和从服务器上都安装了keyring_fileor keyring_encrypted_file插件,但是从服务器上没有密钥环数据文件,则复制的ALTER INSTANCE ROTATE INNODB MASTER KEY语句将在从服务器上创建密钥环数据文件,并假设密钥环文件数据未缓存在内存中。ALTER INSTANCE ROTATE INNODB MASTER KEY使用缓存在内存中的密钥环文件数据(如果有)。

识别加密的表空间和架构
INFORMATION_SCHEMA.INNODB_TABLESPACES 在MySQL 8.0.13中引入 的 表包括一 ENCRYPTION列,可用于标识加密的表空间。

mysql> SELECT SPACE, NAME, SPACE_TYPE, ENCRYPTION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES
       WHERE ENCRYPTION='Y'\G
*************************** 1. row ***************************
     SPACE: 4294967294
      NAME: mysql
SPACE_TYPE: General
ENCRYPTION: Y
*************************** 2. row ***************************
     SPACE: 2
      NAME: test/t1
SPACE_TYPE: Single
ENCRYPTION: Y
*************************** 3. row ***************************
     SPACE: 3
      NAME: ts1
SPACE_TYPE: General
ENCRYPTION: Y

ENCRYPTION在CREATE TABLE或 ALTER TABLE语句中指定选项后, 该选项将 记录在的CREATE_OPTIONS列中 INFORMATION_SCHEMA.TABLES。可以查询此列以标识驻留在每表加密文件表空间中的表。

mysql> SELECT TABLE_SCHEMA, TABLE_NAME, CREATE_OPTIONS FROM INFORMATION_SCHEMA.TABLES
       WHERE CREATE_OPTIONS LIKE '%ENCRYPTION%';
+--------------+------------+----------------+
| TABLE_SCHEMA | TABLE_NAME | CREATE_OPTIONS |
+--------------+------------+----------------+
| test         | t1         | ENCRYPTION="Y" |
+--------------+------------+----------------+

查询 INFORMATION_SCHEMA.INNODB_TABLESPACES 以检索有关与特定架构和表关联的表空间的信息。

mysql> SELECT SPACE, NAME, SPACE_TYPE FROM INFORMATION_SCHEMA.INNODB_TABLESPACES WHERE NAME='test/t1';
+-------+---------+------------+
| SPACE | NAME    | SPACE_TYPE |
+-------+---------+------------+
|     3 | test/t1 | Single     |
+-------+---------+------------+

您可以通过查询INFORMATION_SCHEMA.SCHEMATA表来识别启用加密的架构 。

mysql> SELECT SCHEMA_NAME, DEFAULT_ENCRYPTION FROM INFORMATION_SCHEMA.SCHEMATA
       WHERE DEFAULT_ENCRYPTION='YES'; 
+-------------+--------------------+
| SCHEMA_NAME | DEFAULT_ENCRYPTION |
+-------------+--------------------+
| test        | YES                |
+-------------+--------------------+

SHOW CREATE SCHEMA还显示了该DEFAULT ENCRYPTION条款。

监视加密进度
您可以mysql 使用Performance Schema监视常规表空间和系统表空间的加密进度 。

该stage/innodb/alter tablespace (encryption) 阶段活动的仪器报告WORK_ESTIMATED 和WORK_COMPLETED信息一般表空间加密操作。

以下示例演示了如何启用 stage/innodb/alter tablespace (encryption) 阶段事件工具和相关的使用者表来监视常规表空间或mysql系统表空间加密进度。有关性能架构阶段事件工具和相关使用者的信息,请参见 第26.12.5节“性能架构阶段事件表”。

启用stage/innodb/alter tablespace (encryption)仪器:

mysql> USE performance_schema;
mysql> UPDATE setup_instruments SET ENABLED = 'YES'
       WHERE NAME LIKE 'stage/innodb/alter tablespace (encryption)';

启用舞台活动消费表,其中包括 events_stages_current, events_stages_history,和 events_stages_history_long。

mysql> UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%';

运行表空间加密操作。在此示例中,名为的常规表空间ts1已加密。

mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';

通过查询性能架构events_stages_current表来检查加密操作的进度 。 WORK_ESTIMATED报告表空间中的页面总数。WORK_COMPLETED 报告已处理的页面数。

mysql> SELECT EVENT_NAME, WORK_ESTIMATED, WORK_COMPLETED FROM events_stages_current;
+--------------------------------------------+----------------+----------------+
| EVENT_NAME                                 | WORK_COMPLETED | WORK_ESTIMATED |
+--------------------------------------------+----------------+----------------+
| stage/innodb/alter tablespace (encryption) |           1056 |           1407 |
+--------------------------------------------+----------------+----------------+

events_stages_current如果加密操作已完成,则 该表将返回一个空集。在这种情况下,您可以检查 events_stages_history表以查看事件数据以了解完成的操作。例如:

mysql> SELECT EVENT_NAME, WORK_COMPLETED, WORK_ESTIMATED FROM events_stages_history;
+--------------------------------------------+----------------+----------------+
| EVENT_NAME                                 | WORK_COMPLETED | WORK_ESTIMATED |
+--------------------------------------------+----------------+----------------+
| stage/innodb/alter tablespace (encryption) |           1407 |           1407 |
+--------------------------------------------+----------------+----------------+

加密使用说明
使用该ENCRYPTION选项更改现有的每表文件表空间时,请进行适当的计划。使用该COPY算法重建每表文件表空间中的表。INPLACE更改ENCRYPTION通用表空间或mysql系统表空间的属性时使用该 算法 。该INPLACE算法允许对驻留在常规表空间中的表进行并发DML。并发DDL被阻止。

当对通用表空间或mysql 系统表空间进行加密时,驻留在该表空间中的所有表都将被加密。同样,在加密表空间中创建的表也被加密。

如果服务器在正常操作过程中退出或停止,建议使用与先前配置相同的加密设置重新启动服务器。

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

主密钥轮换会重新加密表空间密钥,但不会更改表空间密钥本身。要更改表空间密钥,必须禁用并重新启用加密。对于每个表文件表空间,重新加密表空间是ALGORITHM=COPY重建表的 操作。对于常规表空间和 mysql系统表空间,这是一项 ALGORITHM=INPLACE操作,不需要重建驻留在表空间中的表。

如果同时使用COMPRESSION 和 ENCRYPTION 选项创建表 ,则在对表空间数据进行加密之前执行压缩。

如果密钥环数据文件(以keyring_file_data或 命名的文件 keyring_encrypted_file_data)为空或丢失,则第一次执行时 ALTER INSTANCE ROTATE INNODB MASTER KEY会创建一个主加密密钥。

卸载keyring_file或 keyring_encrypted_file插件不会删除现有的密钥环数据文件。

建议不要将密钥环数据文件与表空间数据文件放在同一目录下。

在运行时或重新启动服务器时 修改 keyring_file_data或 keyring_encrypted_file_data设置可能会导致无法访问以前加密的表空间,从而导致数据丢失。

InnoDB FULLTEXT添加FULLTEXT索引时隐式创建 的索引表支持加密,但FULLTEXT前提是该索引是在驻留在加密的常规表空间中的表上创建的。在这种情况下,FULLTEXT索引表是在相同的加密通用表空间中创建的。有关相关信息,请参见 InnoDB全文索引表。

加密限制
高级加密标准(AES)是唯一受支持的加密算法。InnoDB表空间加密使用电子密码簿(ECB)块加密模式进行表空间密钥加密,并使用密码块链接(CBC)块加密模式进行数据加密。

仅对每个表文件表 空间, 常规 表空间和mysql系统表空间支持加密 。MySQL 8.0.13中引入了对常规表空间的加密支持。mysql自MySQL 8.0.16起,对系统表空间的加密支持 已可用。其他表空间类型(包括InnoDB 系统表空间)不支持加密。

您不能将表从加密的每表文件表 空间, 常规 表空间或mysql系统表空间移动或复制 到不支持加密的表空间类型。

您不能将表从加密的表空间移动或复制到未加密的表空间。但是,允许将表从未加密的表空间移动到已加密的表空间。例如,您可以将表从未加密的每表文件或 常规 表空间移动或复制 到加密的常规表空间。

默认情况下,表空间加密仅适用于表空间中的数据。启用innodb_redo_log_encrypt和 可以对重做日志和撤消日志数据进行加密 innodb_undo_log_encrypt。请参阅 重做日志加密和 撤消日志加密。有关二进制日志文件和中继日志文件加密的信息,请参见 第17.3.2节“加密二进制日志文件和中继日志文件”。

不允许更改驻留在加密表空间中或以前驻留在其中的表的存储引擎。