MySQL安全相关-- TDE和数据脱敏功能介绍

2022-03-14 14:39:13 浏览数 (2)

罗伟文 多年的DBA经验,从oracle8i到MySQL,从传统行业到互联网,从音乐直播到电子商务,有大规模高并发数据库集群的实战经验,现任甲骨文云MySQL首席解决方案工程师

1 TDE

TDE( Transparent Data Encryption,透明数据加密) 指的是无需修改应用就可以实现数据的加解密,在数据写磁盘的时候加密,读的时候自动解密。加密后其他人即使能够访问数据库文件,没有key也无法读取数据,从而达到防止非法访问的目的。

  • MySQL的支持情况

InnoDB使用的是两层的加密键架构,包括一个master加密键和表空间加密键,master加密键是用来加解密表空间键的,而表空间加密键保持不变,放置在表空间文件的文件头,这样可以不时轮换master的加密键,从而提供更高的安全性,而表空间的数据不用重新进行加解密,节省时间,对生产系统的影响也较小。

静态数据加密功能支持基于高级加密标准 (Advanced EncryptionStandard,AES) 块的加密算法。它使用电码本(Electronic Codebook ) 块加密模式进行表空间密钥加密,使用密码分组链接 (CipherBlock Chaining) 块加密模式进行数据加密。

加密的key都是通过keyring(钥匙圈)来进行管理的,使用的是插件和组件的形式。这些插件或组件使用本身的后台存储或者与其它的密钥后端存储系统通信,MySQL 5.7开始支持TDE,8.0提供更多的加密选项,社区版和企业版都可以,区别是企业版提供额外的keyring组件和插件,可以提供更好的安全性,如果要达到合规的要求,需要使用企业版,详细支持情况列表如下。

keyring 组件名

社区版

企业版

component_keyring_file

8.0.24

8.0.24

component_keyring_encrypted_file

不支持

8.0.24

keyring_file

5.7

5.7

keyring_encrypted_file

不支持

5.7

keyring_okv

不支持

5.7

keyring_aws

不支持

5.7

keyring_hashicorp

不支持

8.0.18

keyring_oci

不支持

8.0.22

对于不同的版本,支持的文件加密也是有区别的,8.0.23或以上,支持的加密包括有:独立表空间、通用表空间、DoubleWrite文件、mysql系统表空间、Redo log和UndoLog文件的加密。

根据官方文档,启用后性能影响百分比在个位数,实际的影响情况可用工作负载测试下。启用加密后,数据库的占用空间也变化不大。

启用加密后,对于备份策略也需要调整,需要考虑到master键的保存,并不时作备份恢复测试,确保即使生产数据完全丢失也可以恢复数据。要注意的是,如果使用MySQL Enterprise Backup (MEB)备份TDE的表空间,备份下来也是加密的,而mysqldump备份是没有加密的,考虑到安全问题可手动加密。

以下演示的是通过插件方式进行的TDE加密,keyring_encrypted_file是企业版带的插件,它将钥匙圈数据存储在一个加密的、用密码保护的本地文件中。

首先,安装插件

mkdir -p /usr/local/mysql/mysql-keyring/

chown mysql:mysql /usr/local/mysql/mysql-keyring/

修改配置文件

[mysqld]

early-plugin-load=keyring_encrypted_file.so

keyring_encrypted_file_data=/usr/local/mysql/mysql-keyring/keyring-encrypted

keyring_encrypted_file_password=password

重新启动后,确认插件是ACTIVE状态

SELECT PLUGIN_NAME, PLUGIN_STATUS

FROM INFORMATION_SCHEMA.PLUGINS

WHERE PLUGIN_NAME LIKE 'keyring%';

要实现通过SQL接口来进行钥匙圈的key管理,还需要安装一个插件keyring_udf.so的插件

INSTALL PLUGIN keyring_udf SONAME'keyring_udf.so';

再次确认插件是否ACTIVE

mysql> SELECT PLUGIN_NAME,PLUGIN_STATUS FROM INFORMATION_SCHEMA.PLUGINS WHERE PLUGIN_NAME LIKE 'keyring%'G

*************************** 1. row***************************

PLUGIN_NAME: keyring_encrypted_file

PLUGIN_STATUS: ACTIVE

*************************** 2. row***************************

PLUGIN_NAME: keyring_udf

PLUGIN_STATUS: ACTIVE

2 rows in set (0.01 sec)

接着创建对应的函数:

CREATE FUNCTION keyring_key_generateRETURNS INTEGER

SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_fetch RETURNSSTRING

SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_length_fetchRETURNS INTEGER

SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_type_fetchRETURNS STRING

SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_store RETURNSINTEGER

SONAME 'keyring_udf.so';

CREATE FUNCTION keyring_key_remove RETURNSINTEGER

SONAME 'keyring_udf.so';

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

Query OK, 0 rows affected (0.02 sec)

确认是否已经加密

mysql> SELECT SPACE, NAME, SPACE_TYPE,ENCRYPTION FROM INFORMATION_SCHEMA.INNODB_TABLESPACES

-> WHEREENCRYPTION='Y'G

*************************** 1. row***************************

SPACE: 2

NAME: test/t1

SPACE_TYPE: Single

ENCRYPTION: Y

1 row in set (0.00 sec)

加密已经完成了,如果在生产中应用,需要注意保存好master加密键,这个步骤建议在创建首个加密表空间后就要马上做个备份,以后如果发生加密键轮换,再继续备份一次。

各种插件和组件的安装和使用方法见:https://dev.mysql.com/doc/refman/8.0/en/keyring.html

2 数据脱敏

数据脱敏,就是将敏感的信息,例如身份证信息、信用卡信息和电话号码等隐藏起来,从而达到保护客户资料隐私的目的。

从8.0.13开始,MySQL企业版提供了数据脱敏的功能,主要包括:

1.转换现有数据,例如将信用卡号只保留最后四个字符,其余数据均更改为“X”字符;

2.随机数据的生成,例如电子邮件地址和信用卡号。

这些功能都是通过安装插件实现的,日常需要数据脱敏的时候,例如测试环境的部署等,

通过使用这些函数可大大方便我们的工作。安装步骤如下:

INSTALL PLUGIN data_masking SONAME 'data_masking.so';

CREATE FUNCTION gen_blacklist RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_dictionary RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_dictionary_drop RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_dictionary_load RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_range RETURNS INTEGER

SONAME 'data_masking.so';

CREATE FUNCTION gen_rnd_email RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_rnd_pan RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_rnd_ssn RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION gen_rnd_us_phone RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION mask_inner RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION mask_outer RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION mask_pan RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION mask_pan_relaxed RETURNS STRING

SONAME 'data_masking.so';

CREATE FUNCTION mask_ssn RETURNS STRING

SONAME 'data_masking.so';

安装好后,我们就可以调用这些函数了。

2.1 数据打码功能

mask_inner() 和mask_outer(),可以根据设定的位置将部分的字符串打码。

例如:mask_inner可将中间部分的字符串打码,下面设置的是除开始的5个字符和最后的一个字符不打码外,其余均打码脱敏

SELECT mask_inner('This is a string', 5,1);

--------------------------------------

| mask_inner('This is a string', 5, 1) |

--------------------------------------

| This XXXXXXXXXXg |

mask_outer的作用则相反,中间不打码,其余均打码

SELECT mask_outer('This is a string', 5,1);

--------------------------------------

| mask_outer('This is a string', 5, 1) |

--------------------------------------

| XXXXXis a strinX

信用卡账号打码,下面先用gen_rnd_pan生成随机的信用卡账号,然后mask_pan,只保留后面4位

mysql> SELECT mask_pan(gen_rnd_pan());

-------------------------

| mask_pan(gen_rnd_pan()) |

-------------------------

| XXXXXXXXXXXX2461 |

-------------------------

2.2 随机数据生成功能

l 生成随机的email地址

例如下面生成example.com域的随机email地址

mysql> SELECT gen_rnd_email();

---------------------------

| gen_rnd_email() |

---------------------------

| ayxnq.xmkpvvy@example.com |

l 取字典中的随机项目

先导入字典,然后随机取出里面项目

下面de_cities.txt存放的是测试的项目,每个一条,通过gen_dictionary_load导入并设置一个标签DE_Cities

mysql> SELECTgen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt', 'DE_Cities');

--------------------------------------------------------------------------------

| gen_dictionary_load('/usr/local/mysql/mysql-files/de_cities.txt','DE_Cities') |

--------------------------------------------------------------------------------

| Dictionary load success |

然后通过DE_Cities标签可以随机取出一个项目

mysql> SELECTgen_dictionary('DE_Cities');

-----------------------------

| gen_dictionary('DE_Cities') |

-----------------------------

| Berlin |

-----------------------------

更多的脱敏函数,可参见

https://dev.mysql.com/doc/refman/8.0/en/data-masking-function-reference.html

关于TDE和数据脱敏,就介绍到这里了,有需要的朋友可以测试下。

0 人点赞