MariaDB/MySQL 表空间加密

2023年02月05日 1248点热度 0人点赞 0条评论

在玩这个之前切记要备份你的数据库,不然玩劈叉了数据就全找不回来了!

MariaDB在10.1.3版本中加入了支持表加密和表空间加密的特性,在10.1.7版本加入了支持binlog加密的特性,这使得我们可以对数据文件和binlog进行加密,避免数据文件、binlog等文件被窃取后破解出关键数据。

一. MariaDB的加密特性

1. innodb表空间加密
2. innodb日志加密
3. binlog加密
4. aria表加密
5. 临时文件加密

加密特性的一些限制:

1. 元数据文件(.frm)目前尚未加密;
2. 目前只有MariaDB server才能解密,mysqlbinlog工具还不支持解析加密后的binlog文件
3. xtrabackup工具目前无法备份/恢复使用了加密特性的MariaDB实例。
4. 慢查询日志和错误日志尚未加密,里面可能会包含原始数据。

二. 使用MariaDB加密

为了保护加密后的数据,密钥一般存放在和数据文件不同的位置。MariaDB的密钥管理方式可以根据不同的保密需求来开发密钥管理插件,在默认情况下可以使用file_key_management插件,该插件以文件的方式存储密钥。
file_key_management插件:


相关参数:
file_key_management_filename:密钥文件位置, 比如/etc/my.cnf.d/file_key.txt
file_key_management_filekey:密钥文件的解密密码,如果密钥文件有加密的话则必须提供
file_key_management_encryption_algorithm:加密算法, AES_CBC/AES_CTR

创建密钥文件(/etc/my.cnf.d/file_key_enc.txt)包含了AES密钥。128, 192 或 256位密钥都可以支持。ID有16个字节。
例子如下:

# MariaDB encryption file key
1;29267E64589E27D5C8C6F9CD56CC2CD4182BC64D8CD5CBE923CBFDC43772EC82
2;6E4918CBD1CDCE81EE4731168FC5CC28967053D185B66D0C7548D624E551112B
3;23CEBC9421FFC028DB3EC7CC32E4D26B265DC0344D58CECE7457CF13C9CF396C
4;42C59ED5F2D911B3CE4FC527FD9BE4C877C2CB11BD858EEF5DEB91EDCC56822B

每行密钥由两部分组成,第一部分是密钥id,紧跟分隔符后面的是十六进制的密钥。
每个表可以单独指定一个密钥id(1-255)。不过innodb系统表空间和日志文件固定使用id为1的密钥来加密,所以密钥文件中一定要有id为1的密钥。如果存在密钥id为2的密钥,则会用来加密临时表和临时文件。

创建密码文件:/etc/my.cnf.d/key.txt
内容为密码:encrypt_key

这里还可以对密钥文件本身进行加密来防止密钥文件外泄,例如把明文的 file_key.txt 文件加密成 file_key_enc.txt ,密码为 encrypt_key

openssl enc -aes-256-cbc -md sha1 -k encrypt_key -in file_key.txt -out file_key_enc.txt
innodb加密选项:
innodb-encrypt-tables:on/off/force, 是否加密所有innodb表, force表示强制加密所有innodb表
innodb-encrypt-log:on/off, 是否加密innodb日志文件
innodb-encryption-rotate-key-age:秒数,如果获取到了新密钥多久更新一次页面加密
innodb-encryption-rotation-iop:IOPS,最多允许用多少IOPS来做页面加密更新
innodb-encryption-threads:线程数,用多少个后台线程来做页面加密更新

binlog加密选项:
encrypt-binlog:on/off,是否加密binlog

其他加密选项:
encrypt_tmp_files:on/off,是否加密临时文件
encrypt_tmp_disk_tables:on/off,是否加密aria临时表
aria_encrypt_tables:on/off,是否加密aria表(只对ROW_FORMAT=PAGE)

完整的配置如下:

[mysqld]
# 表空间加密
plugin-load-add=file_key_management.so
file_key_management_filename = /etc/my.cnf.d/file_key_enc.txt
file_key_management_filekey = FILE:/etc/my.cnf.d/key.txt
file_key_management_encryption_algorithm = AES_CTR

innodb-encrypt-tables=on                # on/off/force, 是否加密所有innodb表, force表示强制加密所有innodb表
innodb-encrypt-log=on                   # on/off, 是否加密innodb日志文件
innodb_encrypt_temporary_tables=on      # on/off, 是否加密临时表
innodb-encryption-threads=4             # 线程数,用多少个后台线程来做页面加密更新
encrypt-binlog=on                       # on/off,是否加密binlog
encrypt_tmp_files=on                    # on/off,是否加密临时文件
encrypt_tmp_disk_tables=on              # on/off,是否加密aria临时表
aria_encrypt_tables=on                  # on/off,是否加密aria表(只对ROW_FORMAT=PAGE)

#添加完成后重启MariaDB服务。

三. 使用实例

创建不加密的表:

create table unencrypt_t(id int, name varchar(32)) ENCRYPTED=NO;

创建加密的表,指定密钥id为3:

create table encrypt_t(id int, name varchar(32)) ENCRYPTED=YES ENCRYPTION_KEY_ID=3;

修改不加密的表为加密:

alter table unencrypt_t ENCRYPTED=YES ENCRYPTION_KEY_ID=3;

修改加密的表为不加密:

alter table unencrypt_t ENCRYPTED=NO;

加密开启后的主备同步:
开启加密后,主机和备机之间的binlog传输是不加密的,由备机在写relaylog/binlog/数据文件时进行加密。所以主备之间的密钥可以不同,但id信息必须一致,否则建表语句在备机上无法执行成功,将会导致slave SQL线程中止。

加密和压缩:
数据加密和数据压缩可以同时使用,MariaDB先做数据压缩再做数据加密,可以节约很大的存储空间。

路灯

这个人很懒,什么都没留下

文章评论