Greenplum数据加密功能前瞻(二):表的透明加密

在这一系列上一篇文章《Greenplum数据加密功能前瞻(一):堆表的存储管理》中,我们简要介绍了Greenplum的堆表中的数据是如何存储在磁盘上,又是如何以文件的形式进行组织和管理的。在这篇文章中,我们将简要介绍如何对表中的数据进行透明加密,在保证数据加密的前提下实现数据加解密过程对用户完全透明,从而同时实现了数据的安全性和系统的易用性。

表的透明加密示例

为了直观地说明数据加密功能是如何保证磁盘上的数据的安全的,我们先用一个简单的例子演示一下启用数据加密功能前后,磁盘上的数据有什么变化。

首先,在未开启数据加密功能的情况下,创建一个数据表,称为unencrypted_table:

gpadmin=# CREATE TABLE unencrypted_table (message TEXT) DISTRIBUTED BY (message);CREATE TABLE

然后,向未加密表中插入一条记录,其中message为“hello, world”:

gpadmin=# INSERT INTO unencrypted_table VALUES ('hello, world');INSERT 0 1

为了查看这条记录在磁盘上是如何存储的,我们需要找到这条记录所在的文件。为此,先定位这条记录所在的GPDB Segment:

gpadmin=# SELECT gp_segment_id, * FROM unencrypted_table ; gp_segment_id |   message    ---------------+--------------             0 | hello, world(1 row)

然后,为了找到存储这条记录的文件,我们需要确定表unenctyped_table在Segment 0上的文件的路径:

gpadmin=# SELECT pg_relation_filepath('unencrypted_table') FROM gp_dist_random('gp_id') WHERE gp_segment_id = 0; pg_relation_filepath ---------------------- base/16384/16451(1 row)

得到文件路径之后,我们需要连接到Segment 0所在的服务器上,进入Segment 0的数据文件夹,找到这条记录所在的数据文件。

找到数据文件后,使用od工具可以查看数据文件的内容:

gpadmin=# \! od -Ad -c --width=8 /home/gpadmin/gpdb/gpAux/gpdemo/datadirs/dbfast1/demoDataDir0/base/16384/164510000000  \0  \0  \0  \0   ` 002   !   p0000008 364  \b  \0  \0 034  \0 330 1770000016  \0 200 016 200  \0  \0  \0  \00000024 330 377   J  \0  \0  \0  \0  \00000032  \0  \0  \0  \0  \0  \0  \0  \0*0032728   5 002  \0  \0  \0  \0  \0  \00032736  \0  \0  \0  \0  \0  \0  \0  \00032744 001  \0 001  \0 002  \b 030  \00032752 215   h   e   l   l   o   ,    0032760   w   o   r   l   d  \0  \0  \00032768
➜ hexdump -C base/16384/16451*00007fd0 00 00 00 00 00 00 00 00 e7 01 00 00 00 00 00 00 |................|00007fe0 00 00 00 00 00 00 00 00 01 00 01 00 02 09 18 00 |................|00007ff0 8d 68 65 6c 6c 6f 2c 20 77 6f 72 6c 64 00 00 00 |.hello, world...|*

可以看到,数据文件结束位置为0032768,表明这个数据文件大小为32KB,即文件中只含有一个块。块内大部分的区域的值都是0(显示为“\0”),说明大部分区域都是空的,只在末尾存储着刚刚写入的那条记录中的“hello, world”。这个“hello, world”是明文存储在文件中的,任何能够访问这个磁盘的人,无论他是否有连接数据库的权限,都能够看到。因此,如果Greenplum所在的机器是委托给第三方管理的,或者发生了磁盘失窃的状况,数据就有可能被泄漏。

接下来,让我们启用数据加密功能,看一下启用之后磁盘上的数据是什么样子的。

首先,在一个启用了数据加密功能的数据库(在本例中为contrib_regression)中创建一张表,这张表会自动被加密。

contrib_regression=# CREATE TABLE encrypted_table (message TEXT) DISTRIBUTED BY (message);CREATE TABLE

同样向这张表中插入一条message为“hello, world”的记录:

contrib_regression=# INSERT INTO encrypted_table VALUES ('hello, world');INSERT 0 1

然后,同样通过gp_semgnet_id属性和pg_relation_filepath()函数确定刚刚插入的这条记录所在的数据文件:

contrib_regression=# SELECT gp_segment_id, * FROM encrypted_table ; gp_segment_id |   message    ---------------+--------------             0 | hello, world(1 row)
contrib_regression=# SELECT pg_relation_filepath('encrypted_table') FROM gp_dist_random('gp_id') WHERE gp_segment_id = 0; pg_relation_filepath ---------------------- base/16391/16496(1 row)

最后同样使用od命令查看数据文件的内容:

[gpadmin@localhost gpdb]$ od -Ad -c --width=8 /home/gpadmin/gpdb/gpAux/gpdemo/datadirs/dbfast1/demoDataDir0/base/16391/16496 | tail -n 60032728   ; 001 254 306 352 263 207 0240032736   o 230 217   n   D 033   6 2660032744 257   : 031 372 207 203 371 3140032752 262 346   l 262 203 241   g 2650032760   H 366 375 245 234  \r   P 3710032768➜ hexdump -C base/16391/16496*00007fd0 0f e7 cf b2 78 27 0b 32 54 0b cb 76 9f 18 aa 4b |....x'.2T..v...K| 00007fe0 14 4f f1 82 f0 3c b6 00 b7 45 2a 1f 4d 82 ad 14 |.O...<...E*.M...| 00007ff0 a0 9d fe b7 75 75 86 ec b3 d3 4b 69 ac f4 8a 6d |....uu....Ki...m|*

与之前未加密的情况不同,此时明文 hello, word 并未出现,说明这个数据文件很多地方原本因为没有数据而应该为0的地方由于加密变成了一串“乱码”,而在未加密的表的数据文件中应该显示“hello, world”的位置也变成了“乱码”。这样,即使有人能够越过Greenplum数据库系统直接访问磁盘,他也不能看到磁盘上的数据。这说明了数据加密功能能够有效地保护用户数据的安全,防止数据泄露。

另外可以看到,在通过更改配置启用数据加密功能后,在加密的数据库上进行增删改查操作与在未加密的数据库上进行增删改查操作别无二致。除DBA外,普通用户进行查询不需要调用加解密函数,也不需要参与密钥的管理。这些过程对用户是透明的。这就是“透明加密”这一名称的由来。透明加密使得数据加密功能学习成本和代码迁移成本都降到了最低。

AO表的透明加密

上面演示的是堆表的透明加密。除了堆表之外,Greenplum数据库还提供了另外一种存储结构,即追加优化(Append-Optimized,简称AO)表。与堆表相比,AO表存储更紧凑,记录和记录之间没有空余空间,在AO表上进行分析通常效率更高。

Greenplum也将支持AO表的透明加密,与堆表类似,配置启用数据加密功能后,AO表在建立时会被自动设置成加密的,之后在数据被插入到AO表时会被自动加密,而在数据被从AO表中读出时会被自动解密。用户在执行查询时同样既不需要显式调用加解密函数,也不需要关心密钥的管理,这些过程会由Greenplum自动完成。

从技术上来说,AO表透明加密的原理与堆表类似,即对于每个数据块,当它被从内存写到磁盘时利用加密函数对其加密;当它被从磁盘读到内存时使用解密函数对其解密。与堆表不同,AO表的数据块不是定长的而是变长的,因此需要使用块头部的信息确定块的大小。因此,AO表数据块的头部是不加密的,只有块内数据加密。由于块头部并不存储用户数据,这一设计不会对数据安全性造成实质性影响。

关注微信公众号

VMware 中国研发中心

Greenplum官方技术交流群

扫码添加小助手即可入群,添加时请备注 “GP网站”