Documentation Home
MySQL 8.4 Reference Manual
Related Documentation Download this Manual
PDF (US Ltr) - 39.8Mb
PDF (A4) - 39.9Mb
Man Pages (TGZ) - 257.9Kb
Man Pages (Zip) - 364.9Kb
Info (Gzip) - 4.0Mb
Info (Zip) - 4.0Mb


MySQL 8.4 Reference Manual  /  The InnoDB Storage Engine  /  InnoDB Data-at-Rest Encryption

17.13 InnoDB 静态数据加密

InnoDB 支持文件-per-表表空间、公共表空间、mysql系统表空间、redo日志和undo日志的静态数据加密。

您可以为模式和公共表空间设置加密默认值,这样DBAs就可以控制在这些模式和表空间中创建的表是否加密。

InnoDB静态数据加密功能和能力在本节下面的主题中进行描述。

InnoDB 使用了两级加密密钥架构,包括主加密密钥和表空间密钥。当一个表空间被加密时,表空间密钥将被加密并存储在表空间头部。应用程序或认证用户想要访问加密表空间数据时,InnoDB 使用主加密密钥来解密表空间密钥。解密后的表空间密钥从不改变,但主加密密钥可以根据需要更改。这一操作称为master key rotation

数据静态加密特性依赖于keyring组件或插件来管理主加密密钥。

所有MySQL版本都提供了component_keyring_file组件,该组件将keyring数据存储在服务器主机的本地文件中。

MySQL Enterprise Edition还提供了额外的keyring组件和插件:

  • component_keyring_encrypted_file:将keyring数据存储在加密、密码保护的本地文件中。

  • keyring_okv:KMIP 1.1插件,用于与KMIP兼容的后端keyring存储产品。支持的KMIP兼容产品包括中央化密钥管理解决方案,如Oracle Key Vault、Gemalto KeySecure、Thales Vormetric密钥管理服务器和Fornetix Key Orchestration。

  • keyring_aws:与Amazon Web Services Key Management Service(AWS KMS)通信,以便在后端生成密钥,并使用本地文件存储密钥。

  • keyring_hashicorp:与HashiCorp Vault通信,以便在后端存储密钥。

Warning

为了加密密钥管理,component_keyring_filecomponent_keyring_encrypted_file 组件不是作为法规遵从性解决方案。安全标准,如PCI、FIPS等,要求使用密钥管理系统来保护和管理加密密钥,在密钥库或硬件安全模块(HSM)中。

一个安全且robust的加密密钥管理解决方案对于安全和遵从各种安全标准是至关重要的。当数据静态加密特性使用集中式密钥管理解决方案时,该特性被称为MySQL Enterprise Transparent Data Encryption(TDE)”

数据静态加密特性支持Advanced Encryption Standard(AES)块加密算法。它使用Electronic Codebook(ECB)块加密模式对表空间密钥进行加密,并使用Cipher Block Chaining(CBC)块加密模式对数据进行加密。

关于数据静态加密特性的常见问题,请参阅第A.17节,“MySQL 8.4 FAQ: InnoDB Data-at-Rest Encryption”

  • 必须在启动时安装和配置密钥ring组件或插件。早期加载确保组件或插件在InnoDB存储引擎初始化之前可用。关于密钥ring安装和配置的指南,请参阅第8.4.4节,“The MySQL Keyring”。该指南显示如何确保选择的组件或插件处于活动状态。

    在 MySQL 实例中,只能启用一个密钥环组件或插件。启用多个密钥环组件或插件是未支持的,可能会导致结果与预期不同。

    Important

    创建加密表空间后,在 MySQL 实例启动时,用于创建加密表空间的密钥环组件或插件必须继续被加载。如果否则,服务器启动和 InnoDB 恢复过程中将出现错误。

  • 在生产数据加密时,请确保采取措施防止主加密密钥丢失。如果主加密密钥丢失,存储在加密表空间文件中的数据将不可恢复。如果使用 component_keyring_ 组件,请立即备份密钥环数据文件,在创建第一个加密表空间后、主密钥轮转前和主密钥轮转后。每个组件的配置文件中都指明了数据文件的位置。如果使用 keyring_ 插件,请确保已经进行了必要的配置。详细信息请见第8.4.4节,“MySQL密钥环”

为模式和一般表空间定义加密默认值

default_table_encryption 系统变量定义了对架构和公共表空间的默认加密设置。CREATE TABLESPACECREATE SCHEMA 操作在不指定明确的ENCRYPTION子句时将应用default_table_encryption设置。

ALTER SCHEMAALTER TABLESPACE 操作不应用default_table_encryption设置。要更改现有架构或公共表空间的加密,必须指定明确的ENCRYPTION子句。

可以使用default_table_encryption变量在个体客户端连接或全局设置。例如,以下语句将对架构和公共表空间的加密设置为全局:

mysql> SET GLOBAL default_table_encryption=ON;

可以使用DEFAULT ENCRYPTION子句在创建或修改架构时定义默认加密设置,例如:

mysql> CREATE SCHEMA test DEFAULT ENCRYPTION = 'Y';

如果在创建架构时未指定DEFAULT ENCRYPTION子句,則将应用default_表_加密设置。要修改现有架构的默认加密设置,必须指定DEFAULT ENCRYPTION子句;否则,架构将保留其当前加密设置。

默认情况下,表继承了它创建时所在架构或公共表空间的加密设置。例如,在加密启用的架构中创建的表默认是加密的。这一行为使DBA能够通过定义和强制架构和公共表空间加密默认来控制表加密使用。

加密默认值由启用table_encryption_privilege_check系统变量来强制执行。当table_encryption_privilege_check启用时,在创建或更改具有不同加密设置的架构或通用表空间、或创建或更改与默认架构加密不同的表时,会发生权限检查。当table_encryption_privilege_check禁用(默认)时,不会发生权限检查,并且将在警告中继续执行前述操作。

需要TABLE_ENCRYPTION_ADMIN特权来覆盖默认加密设置,当table_encryption_privilege_check启用时。DBA可以授予该特权,以便用户在创建或更改架构或通用表空间时,可以偏离default_table_encryption设置,也可以偏离默认架构加密when创建或更改表。该特权不允许在创建或更改表时偏离通用表空间的加密设置。表必须与其所在的通用表空间具有相同的加密设置。

File-Per-Table 表space 加密

文件表空间继承了在创建该表时的架构的默认加密设置,除非在CREATE TABLE语句中指定了明确的ENCRYPTION子句。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';

要更改现有文件表空间的加密设置,必须指定ENCRYPTION子句。

mysql> ALTER TABLE t1 ENCRYPTION = 'Y';

table_encryption_privilege_check 已启用,指定与默认架构加密不同的ENCRYPTION子句需要TABLE_ENCRYPTION_ADMIN权限。请参阅定义架构和一般表空间的加密默认值

一般表space 加密

default_table_encryption 变量确定新创建的一般表space 的加密,除非在CREATE TABLESPACE 语句中显式指定ENCRYPTION子句。

mysql> CREATE TABLESPACE `ts1` ADD DATAFILE 'ts1.ibd' ENCRYPTION = 'Y' Engine=InnoDB;

要更改现有一般表space 的加密,必须指定ENCRYPTION子句。

mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';

如果启用了table_encryption_privilege_check,指定一个与default_table_encryption设置不同的ENCRYPTION子句需要TABLE_ENCRYPTION_ADMIN权限。请参阅定义 schema 和通用表空间的加密默认值

在 MySQL 8.4 中,InnoDB 自动将属于加密表空间的双写文件页加密。无需执行任何操作。使用关联表空间的加密密钥加密的双写文件页写入到表空间数据文件中也会被写入到双写文件中。属于未加密表空间的双写文件页保持未加密状态。

在恢复过程中, 加密的双写文件页将被解密并检查是否损坏。

mysql 系统表空间加密

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

mysql> ALTER TABLESPACE mysql ENCRYPTION = 'Y';

要禁用mysql系统表空间的加密,请使用ALTER TABLESPACE语句将ENCRYPTION = 'N'设置为'N'

mysql> ALTER TABLESPACE mysql ENCRYPTION = 'N';

启用或禁用mysql系统表空间的加密需要在实例中拥有CREATE TABLESPACE特权权限(CREATE TABLESPACE on *.*))。

重做日志加密

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

与表空间数据类似,重做日志数据加密发生在写入磁盘时,解密发生在读取磁盘时。从磁盘读取到内存后,重做日志数据将变为未加密的形式。重做日志数据使用表空间加密密钥进行加密和解密。

innodb_redo_log_encrypt启用时,磁盘上存在的未加密redo日志页将保持未加密状态,而新的redo日志页将以加密形式写入磁盘。同样,当innodb_redo_log_encrypt禁用时,磁盘上存在的加密redo日志页将保持加密状态,而新的redo日志页将以未加密形式写入磁盘。

redo日志加密元数据,包括表空间加密密钥,在redo日志文件中最 recent 检查点LSN的头部存储。如果删除了包含加密元数据的redo日志文件,redo日志加密将被禁用。

启用redo日志加密后,正常启动不可能,因为InnoDB在启动时必须能够扫描redo页,这在redo页加密的情况下不可行。没有keyring组件或插件或加密密钥,只能强制启动,不使用redo日志(SRV_FORCE_NO_LOG_REDO)。请参阅第17.20.3节,“强制InnoDB恢复”

undo日志数据加密使用innodb_undo_log_encrypt配置选项启用。undo日志加密适用于undo表空间中的undo日志。请参阅第17.6.3.4节,“Undo Tablespaces”。undo日志数据加密默认处于禁用状态。

与表空间数据类似,undo日志数据加密发生在写入磁盘时,并在读取磁盘时解密。将undo日志数据读入内存后,它将变为未加密形式。undo日志数据使用表空间加密密钥进行加密和解密。

innodb_undo_log_encrypt启用时,磁盘上存在未加密的undo日志页将保持未加密状态,而新的undo日志页将写入磁盘以加密形式。相反,当innodb_undo_log_encrypt禁用时,磁盘上存在加密的undo日志页将保持加密状态,而新的undo日志页将写入磁盘以未加密形式。

undo日志加密元数据,包括表空间加密密钥,在undo日志文件头中存储。

Note

当undo日志加密disabled时,服务器将继续要求用于加密undo日志数据的keyring组件或插件,直到包含加密undo日志数据的undo表空间被截断。 (只有在undo表空间被截断时,undo表空间中的加密头部才会被删除。) 关于截断undo表空间的信息,请参见截断Undo表空间

主密钥应该定期旋转,并且在您怀疑密钥已被 compromised时旋转。

主密钥旋转是一个原子、实例级别的操作。每次旋转主密钥时,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将在服务器重启时继续该操作。

keyring组件或插件必须在存储引擎初始化之前加载,以便从表空间头部中检索必要的信息以解密表空间数据页。 (请参阅加密前提。)

InnoDB初始化和恢复开始时,主密钥轮换操作将继续。由于服务器故障,一些表空间密钥可能已经使用新的主加密密钥进行加密。InnoDB从每个表空间头部读取加密数据,如果数据表明该表空间密钥使用的是旧的主加密密钥,InnoDB从密钥环中检索旧密钥并使用它来解密表空间密钥。InnoDB然后将表空间密钥重新加密使用新的主加密密钥,并将重新加密后的表空间密钥保存回表空间头部。

导出加密的表空间

仅支持文件-per-表文件表空间的导出。

当导出加密的表空间时,InnoDB将生成一个transfer key用于加密表空间密钥。加密后的表空间密钥和 transfer key 将存储在一个tablespace_name.cfp文件中。这两个文件一起需要执行导入操作。在导入时,InnoDB将使用 transfer key 解密表空间密钥在tablespace_name.cfp文件中。有关相关信息,请参见第17.6.1.3节,“导入InnoDB表”

加密和复制

识别加密的表空间和模式

信息_schemaINNODB_TABLESPACES表包含一个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

CREATE TABLEALTER TABLE语句中指定ENCRYPTION选项时,它将被记录在INFORMATION_ SCHEMA.TABLESCREATE_OPTIONS列中。这一列可以用来识别存储在加密文件表空间中的表。

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" |
+--------------+------------+----------------+

查询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     |
+-------+---------+------------+

可以通过查询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子句。

可以使用Performance Schema来监控总体表空间和mysql系统表空间加密进度。

stage/innodb/alter tablespace (加密) 阶段事件仪器报告了通用表空间加密操作的 WORK_ESTIMATEDWORK_COMPLETED 信息。

以下示例演示如何启用 stage/innodb/alter tablespace (加密) 阶段事件仪器和相关的消费者表,以监控通用表空间或 mysql 系统表空间加密进度。关于性能_schema 阶段事件仪器和相关消费者的信息,请见第29.12.5节,“性能_schema 阶段事件表”

  1. 启用 stage/innodb/alter tablespace (加密) 仪器:

    mysql> USE performance_schema;
    mysql> UPDATE setup_instruments SET ENABLED = 'YES'
           WHERE NAME LIKE 'stage/innodb/alter tablespace (encryption)';
  2. 启用阶段事件消费者表,这些表包括events_stages_currentevents_stages_historyevents_stages_history_long

    mysql> UPDATE setup_consumers SET ENABLED = 'YES' WHERE NAME LIKE '%stages%';
  3. 运行表空间加密操作。在这个示例中,一个通用表空间名为 ts1 被加密。

    mysql> ALTER TABLESPACE ts1 ENCRYPTION = 'Y';
  4. 通过查询性能chema的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算法重建。在更改ENCRYPTION属性的通用表空间或mysql系统表空间时,将使用INPLACE算法。INPLACE算法允许对通用表空间中的表进行并发DML操作,但会阻止并发DDL操作。

  • 当通用表空间或mysql系统表空间被加密时,所有在该表空间中的表都将被加密。类似地,在加密表空间中创建的表也将被加密。

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

  • 第一个主密钥是在首次加密表空间时生成的。

  • 主密钥轮换重新加密表空间密钥,但不改变表空间密钥本身。要更改表空间密钥,您必须禁用并重新启用加密。对于文件-每个表空间,重新加密表空间是一个ALGORITHM=COPY操作,该操作重建了表。对于一般表空间和mysql系统表空间,它是一个ALGORITHM=INPLACE操作,不需要重建在该表空间中的表。

  • 如果创建一个同时具有COMPRESSIONENCRYPTION选项的表,压缩将在加密表空间数据之前进行。

  • 卸载component_keyring_filecomponent_keyring_encrypted_file组件不删除现有密钥环数据文件。

  • 建议不要将密钥环数据文件置于表空间数据文件目录下。

  • 加密支持InnoDB FULLTEXT索引表,这些表在添加FULLTEXT索引时隐式创建。有关相关信息,请参阅InnoDB Full-Text Index Tables