searchusermenu
  • 发布文章
  • 消息中心
点赞
收藏
评论
分享
原创

[MySQL 内核原理] MySQL透明加密原理

2023-04-10 07:52:22
321
0

MySQL透明加密概述

透明加密TDE

透明加密,是指文件在使用过程中自动的进行加密解密,无需用户干预,用户实际上是无感的。存储的文件在磁盘上始终是密文,一旦离开使用环境,加密的文件无法打开或打开是乱码,从而起到保护文件内容的效果。

MySQL透明加密功能

MySQL提供透明加密功能,对数据文件进行加密,可以加密的文件包括:

  • Innodb引擎的数据文件(表加密/redo log加密/undo log加密)
  • Binlog/Relay log文件
  • 持久化的系统变量文件
  • 审计日志文件(企业版特性)

在不影响MySQL实例使用、对用户数据库操作无感的情况下,对存储文件进行加密/解密操作。

 

MySQL透明加密分析

以Innodb引擎的表加密为例,对MySQL的透明加密进行分析。

密钥管理组件

MySQL提供密钥管理组件来获取并维护透明加密使用的密钥,密钥管理组件以插件(Keyring Plugin)的方式装载在MySQL实例中。

 

在MySQL Server层,Keyring Plugin通过与不同的密钥管理服务器进行交互,生成、获取密钥并对密钥进行管理。在Innodb引擎层,通过Keyring插件提供的标准接口(包括generate key、fetch key等)提供加密使用的密钥。

 

当前MySQL实现的Keyring插件包括:

  • keyring_file(开源版本):基于本地文件的密钥管理插件
  • keyring_encrypted_file(企业版):基于本地文件的密钥管理插件,文件为加密文件。
  • keyring_okv(企业版):基于Key Management Interoperability Protocol (KMIP) 协议的密钥管理插件。
  • keyring_aws(企业版):基于Amazon Web Services Key Management 的密钥管理插件。
  • keyring_hashicorp(企业版):基于hashicorp vault的密钥管理插件
  • keyring_oci(企业版):基于Oracle Cloud Infrastructure Vault的密钥管理插件

 

大多数为企业版定制的Keyring插件,这里可以根据实际的KMS(Key Management service)来定制Keyring插件。

 

Innodb表加密

Innodb引擎的表解密使用二次加密的方式进行加密,通过Keyring插件获取到的密钥并不直接用来加密数据,而是用来对数据加密的密钥进行加密。

加密使用

Innodb引擎表可以在创建表时指定表加密:

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

或者通过修改表的属性来指定表加密:

mysql> ALTER TABLE t1 ENCRYPTION = 'Y';

 

当指定表加密时,需要至少装载了一种Keyring插件,来获取密钥。如果未装载任何Keyring插件会执行DDL失败。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring plugin is loaded and initialized successfully.

密钥获取

Innodb引擎表加密使用二次加密的方式,涉及到两个密钥:

  • 数据加密密钥:用来对表中的记录进行加密;
  • 密钥加密密钥:用来对数据加密密钥进行加密的密钥;

数据加密密钥是在创建表或者修改表加密属性时随机生成的密钥:

# 在初始化表的文件内存结构时,随机生成用来加密的密钥
fsp_header_init
| fsp_header_fill_encryption_info
  | Encryption::random_value(space->encryption_key);
  | Encryption::random_value(space->encryption_iv);

密钥加密密钥是通过Keyring插件获取的外部输入的密钥,对随机生成的数据加密密钥进行加密,并持久化到文件中:

fsp_header_init
| fsp_header_fill_encryption_info
  # 1 通过keyring插件获取密钥
  | Encryption::get_master_key(&master_key_id …

  # 2 缓存随机生成的数据加密密钥
  | memcpy(key_info,space->encryption_key, ENCRYPTION_KEY_LEN);
  | memcpy(key_info,space->encryption_iv, ENCRYPTION_KEY_LEN);

  # 3 对密钥进行加密
  | my_aes_encrypt(key_info,ENCRYPTION_KEY_LEN * 2, ptr, … 

数据加密

在第一次使用加密表时,需要通过Keyring插件获取外部密钥,通过外部密钥将文件中的数据加密密钥进行解密,并缓存到实例中,用于后续对数据进行加密/解密:

fsp_header_get_encryption_key
| fsp_header_decode_encryption_info
  # 1. 通过keyring插件获取密钥
  | Encryption::get_master_key(master_key_id …

  # 2. 使用外部密钥对文件中的数据加密密钥进行解密
  #    缓存在内容中,用于后续数据的加密和解密
  | my_aes_decrypt( …  key_info …

对于表中的数据文件进行加密/解密,只有在IO操作时进行,所有存放在内存的数据页(PAGE)均为解密后的明文数据:

fil_io
# 使用space中暂存的数据加密密钥
| req_type.encryption_key(space->encryption_key …

# 1. IO读操作
| os_file_read(req_type, node->handle, buf, offset, len)

# 2. IO写操作
| os_file_write( req_type, node->name, node->handle …

总结

MySQL透明加密功能总结如下:

  1. MySQL通过Keyring插件与外部进行交互,提供给用户自定义密钥输入的接口。
  2. 在Innodb引擎的表加密中,使用二次加密的方式进行加密。
  3. 数据加密密钥为内部随机生成的密钥(RANDOM KEY)。
  4. 外部输入的密钥(INPUT KEY)只用来加密数据加密密钥(RANDOM KEY)。
  5. 加密后的数据加密密钥和加密后的数据一同存放在表文件中

 

透明加密的原理图如下:

 

0条评论
0 / 1000
slwang001
1文章数
0粉丝数
slwang001
1 文章 | 0 粉丝
slwang001
1文章数
0粉丝数
slwang001
1 文章 | 0 粉丝
原创

[MySQL 内核原理] MySQL透明加密原理

2023-04-10 07:52:22
321
0

MySQL透明加密概述

透明加密TDE

透明加密,是指文件在使用过程中自动的进行加密解密,无需用户干预,用户实际上是无感的。存储的文件在磁盘上始终是密文,一旦离开使用环境,加密的文件无法打开或打开是乱码,从而起到保护文件内容的效果。

MySQL透明加密功能

MySQL提供透明加密功能,对数据文件进行加密,可以加密的文件包括:

  • Innodb引擎的数据文件(表加密/redo log加密/undo log加密)
  • Binlog/Relay log文件
  • 持久化的系统变量文件
  • 审计日志文件(企业版特性)

在不影响MySQL实例使用、对用户数据库操作无感的情况下,对存储文件进行加密/解密操作。

 

MySQL透明加密分析

以Innodb引擎的表加密为例,对MySQL的透明加密进行分析。

密钥管理组件

MySQL提供密钥管理组件来获取并维护透明加密使用的密钥,密钥管理组件以插件(Keyring Plugin)的方式装载在MySQL实例中。

 

在MySQL Server层,Keyring Plugin通过与不同的密钥管理服务器进行交互,生成、获取密钥并对密钥进行管理。在Innodb引擎层,通过Keyring插件提供的标准接口(包括generate key、fetch key等)提供加密使用的密钥。

 

当前MySQL实现的Keyring插件包括:

  • keyring_file(开源版本):基于本地文件的密钥管理插件
  • keyring_encrypted_file(企业版):基于本地文件的密钥管理插件,文件为加密文件。
  • keyring_okv(企业版):基于Key Management Interoperability Protocol (KMIP) 协议的密钥管理插件。
  • keyring_aws(企业版):基于Amazon Web Services Key Management 的密钥管理插件。
  • keyring_hashicorp(企业版):基于hashicorp vault的密钥管理插件
  • keyring_oci(企业版):基于Oracle Cloud Infrastructure Vault的密钥管理插件

 

大多数为企业版定制的Keyring插件,这里可以根据实际的KMS(Key Management service)来定制Keyring插件。

 

Innodb表加密

Innodb引擎的表解密使用二次加密的方式进行加密,通过Keyring插件获取到的密钥并不直接用来加密数据,而是用来对数据加密的密钥进行加密。

加密使用

Innodb引擎表可以在创建表时指定表加密:

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

或者通过修改表的属性来指定表加密:

mysql> ALTER TABLE t1 ENCRYPTION = 'Y';

 

当指定表加密时,需要至少装载了一种Keyring插件,来获取密钥。如果未装载任何Keyring插件会执行DDL失败。

mysql> CREATE TABLE t1 (c1 INT) ENCRYPTION = 'Y';
ERROR 3185 (HY000): Can't find master key from keyring, please check in the server log if a keyring plugin is loaded and initialized successfully.

密钥获取

Innodb引擎表加密使用二次加密的方式,涉及到两个密钥:

  • 数据加密密钥:用来对表中的记录进行加密;
  • 密钥加密密钥:用来对数据加密密钥进行加密的密钥;

数据加密密钥是在创建表或者修改表加密属性时随机生成的密钥:

# 在初始化表的文件内存结构时,随机生成用来加密的密钥
fsp_header_init
| fsp_header_fill_encryption_info
  | Encryption::random_value(space->encryption_key);
  | Encryption::random_value(space->encryption_iv);

密钥加密密钥是通过Keyring插件获取的外部输入的密钥,对随机生成的数据加密密钥进行加密,并持久化到文件中:

fsp_header_init
| fsp_header_fill_encryption_info
  # 1 通过keyring插件获取密钥
  | Encryption::get_master_key(&master_key_id …

  # 2 缓存随机生成的数据加密密钥
  | memcpy(key_info,space->encryption_key, ENCRYPTION_KEY_LEN);
  | memcpy(key_info,space->encryption_iv, ENCRYPTION_KEY_LEN);

  # 3 对密钥进行加密
  | my_aes_encrypt(key_info,ENCRYPTION_KEY_LEN * 2, ptr, … 

数据加密

在第一次使用加密表时,需要通过Keyring插件获取外部密钥,通过外部密钥将文件中的数据加密密钥进行解密,并缓存到实例中,用于后续对数据进行加密/解密:

fsp_header_get_encryption_key
| fsp_header_decode_encryption_info
  # 1. 通过keyring插件获取密钥
  | Encryption::get_master_key(master_key_id …

  # 2. 使用外部密钥对文件中的数据加密密钥进行解密
  #    缓存在内容中,用于后续数据的加密和解密
  | my_aes_decrypt( …  key_info …

对于表中的数据文件进行加密/解密,只有在IO操作时进行,所有存放在内存的数据页(PAGE)均为解密后的明文数据:

fil_io
# 使用space中暂存的数据加密密钥
| req_type.encryption_key(space->encryption_key …

# 1. IO读操作
| os_file_read(req_type, node->handle, buf, offset, len)

# 2. IO写操作
| os_file_write( req_type, node->name, node->handle …

总结

MySQL透明加密功能总结如下:

  1. MySQL通过Keyring插件与外部进行交互,提供给用户自定义密钥输入的接口。
  2. 在Innodb引擎的表加密中,使用二次加密的方式进行加密。
  3. 数据加密密钥为内部随机生成的密钥(RANDOM KEY)。
  4. 外部输入的密钥(INPUT KEY)只用来加密数据加密密钥(RANDOM KEY)。
  5. 加密后的数据加密密钥和加密后的数据一同存放在表文件中

 

透明加密的原理图如下:

 

文章来自个人专栏
文章 | 订阅
0条评论
0 / 1000
请输入你的评论
0
0