MariaDB 10.1.3 上的表和表空间加密

请注意,本文现已过时。请参阅 MariaDB 10.1 上的表和表空间加密

引言

目前,完全支持加密的引擎只有 XtraDB 和 InnoDB。Aria 存储引擎也支持加密,但仅限于临时表。

MariaDB 支持 2 种不同的方式在 InnoDB/XtraDB 中加密数据

  1. 指定表加密:只有您使用 PAGE_ENCRYPTION=1 创建的表才会被加密。此功能由 eperi 创建。
  2. 表空间加密:所有内容都已加密(包括日志文件)。此功能由 Google 创建,并基于其 MySQL 分支

InnoDB 指定表加密

指定表加密意味着您可以选择要加密哪些表。这允许您在安全性和速度之间进行平衡。要使用表加密,您需要

  • 将 encryption-algorithm 的值设置为您选择的算法。
  • 加载 file-key-management-plugin(或类似的插件)
  • 定义密钥文件的位置
  • 创建密钥

示例

# Table level encryption configuration
plugin-load-add=file_key_management_plugin.so
file-key-management-plugin
file-key-management-plugin-filename=/mnt/dfs/keys.txt
encryption-algorithm=aes_ctr

可以使用 OpenSSL 通过以下命令生成密钥

shell>openssl enc -aes-256-ctr -k mypass -P -md sha1
salt=BFA606C6079DAD33
key=3DB1F43A606DA6ADF4AEB25B44A5E5FE2126EDEACF5AF8DF7B982D8143191936
iv =21C4592A16C870DD47B162F8959E562F

密钥文件是一个文本文件,包含密钥 ID、十六进制编码的 IV 和十六进制编码的密钥。使用上面生成的密钥的 keys.txt 示例

1;21C4592A16C870DD47B162F8959E562F;3DB1F43A606DA6ADF4AEB25B44A5E5FE2126EDEACF5AF8DF7B982D8143191936

在此之后,由数据库设计者选择包含敏感数据的表进行加密。加密可以在表创建时或使用 ALTER TABLE 对表启用。例如

CREATE TABLE customer(CUSTOMER_ID BIGINT NOT NULL PRIMARY KEY, CUSTOMER_NAME VARCHAR(80), CUSTOMER_CREDITCARD VARCHAR(20)) ENGINE=InnoDB page_encryption=1 page_encryption_key=1;
ALTER TABLE sales page_encryption=1 page_encryption_key=1;

在表加密中,当前无法更改密钥,但可以使用 ALTER TABLE 更改使用的密钥。如果未提供密钥标识符,则使用默认密钥。默认密钥可以在 my.cnf 中设置如下

innodb_default_page_encryption_key=4

或使用全局设置动态设置

set global innodb_default_page_encryption_key=4;

例如,使用默认密钥

create table t1(a int not null primary key) engine=innodb page_encryption=1;

InnoDB 表空间加密

在表空间加密中,所有 InnoDB 表都已加密。此外,您还可以加密 InnoDB 日志文件、Aria 表 (ROW_FORMAT=PAGE) 和 Aria 临时表。要使用表空间加密,您需要

  •  将 encryption-algorithm 的值设置为您选择的算法。
  • 加载 example-key-management-plugin(或类似的插件)

示例

# Tablespace encryption configuration
encryption-algorithm=aes_ctr
innodb-encrypt-tables
plugin-load-add=example_key_management_plugin.so
example_key_management_plugin
# encrypt Aria tables
aria
aria-encrypt-tables
# encrypt tmp tables
encrypt-tmp-disk-tables
# encrypt InnoDB log files
innodb-encrypt-log
# key rotation
innodb-encryption-threads=4
innodb-encryption-rotate-key-age=1800

在表空间加密中,密钥不是静态的。取而代之的是所谓的密钥轮换。在密钥轮换中,如果页面上使用的密钥早于 innodb-encryption-rotate-key-age 秒,则更改使用的加密密钥。

InnoDB 表空间清理

清理意味着有一个后台进程会定期扫描所有表并升级页面的加密密钥。这作为 purge(非压缩)的一部分发生,或者通过扫描整个表空间进行清理(已添加到密钥轮换线程中)。Purge 是 InnoDB 内部运行的一种垃圾回收机制,用于提高性能。此功能的配置可能如下所示

# InnoDB Tablespace scrubbing 
innodb-immediate_scrub_data_uncompressed
innodb-background-scrub-data-uncompressed
innodb-background-scrub-data-compressed
# check if spaces needs scrubbing every 500 seconds
innodb_background_scrub_data_check_interval=500
# scrub spaces that were last scrubbed longer than 1800 seconds
innodb_background_scrub_data_interval=1800

性能影响

对表或表空间进行加密自然会对系统的整体性能产生一定影响。性能影响程度取决于所用硬件、工作负载和所用加密方法。本节的目的是给出一些指示,说明与不使用加密的设置相比,使用表加密或表空间加密时对性能有多少影响。

所有实验均在 Intel Xeon E5-2690 @ 2.9GHz CPU 上进行,该 CPU 包含 2 个插槽,每个插槽有 8 个核心,使用超线程,总共有 32 个核心,以及 Linux 3.4.12 系统,内存为 132G。数据库存储在 Fusion-io ioDrive2 Duo 2.41TB 固件 v7.2.5, rev 110646, 驱动程序 3.3.4 build 5833069 上。数据库文件系统使用 NVMFS,所有测试日志和输出存储在第二个 ioDrive 上,使用 EXT4 文件系统。我们使用 Percona 的在线事务处理 (OLTP) 基准测试 https://code.launchpad.net/~percona-dev/perconatools/tpcc-mysql。这种类似 TPC-C 的工作负载涉及五种并发事务类型的混合,这些事务在线执行或排队延迟执行。数据库由九个表组成,记录和填充大小范围广泛。结果以每分钟事务数 (tpmC) 为单位衡量。我们将使用 1000 个仓库,生成约 100G 的数据库,缓冲池大小为 50G,以便整个数据库无法完全放入缓冲池。此外,我们将仅使用 InnoDB 插件作为存储引擎。最后,我们使用 3 小时的测量时间。

在第一个图中,我们比较了普通 InnoDB 表(未加密的表)、页面加密的表、使用被动密钥轮换和清理(将两个间隔都设置得大于测试时间)以及表空间加密(图表中显示为 Google 完全加密)上的 tpmC 结果。

encryption_tpcc2

结论

MariaDB Corporation 谨向 eperi 和 Google 对 MariaDB 做出的贡献表示感谢。