更新时间:2024-11-12 GMT+08:00
分享

透明数据加密

透明加密提供表级数据加密存储功能。当用户使用本特性提供的语法创建加密表后,数据库向磁盘写入加密表数据前,会自动将其加密;同时,数据库从磁盘读取加密表数据后,会自动将其解密。向加密表中进行数据插入、更新、查询和删除等语法与非加密表一致。

  • 透明加密基本原理请参见《特性描述》的“数据库安全 > 透明数据加密”章节。
  • 使用透明加密前需联系管理员配置开启该功能。

查看透明加密基本配置

  1. 查看透明加密功能是否已开启

    enable_tde取值为on时表示开启,取值为off是表示关闭。该参数由管理员设置。
    gaussdb=# SHOW enable_tde;
     enable_tde
    ------------
     on
    (1 row)

  2. 查看是否已设置访问密钥管理服务的参数

    tde_key_info参数为空时表示未设置,tde_key_info不为空时表示已设置。该参数由管理员设置。
    gaussdb=# show tde_key_info;
          tde_key_info
    -------------------------
     keyType=...

操作加密表

  1. 创建加密表。

    创建表时,通过在WITH子句中设置enable_tde=on参数,即可设置该表为加密表。

    数据库默认使用'AES_128_CTR'算法对加密表进行加密,如需使用其他算法,可通过encrypt_algo参数设置。

    gaussdb=# CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (enable_tde = on);
    CREATE TABLE
    gaussdb=# CREATE TABLE t2 (c1 INT, c2 TEXT) WITH (enable_tde = on, encrypt_algo = 'SM4_CTR');
    CREATE TABLE

  2. 查看加密表基本信息。

    加密表基本信息存储在pg_class系统表中的reloptions字段中。其中,dek_cipher为数据密钥密文,由数据库自动生成,并由密钥管理服务加密。每个加密表都有1个独立的数据密钥。
    gaussdb=# SELECT relname,reloptions FROM pg_class WHERE relname = 't1';
     relname | reloptions
    ---------+-----------------------------------------------------------------------------------------------------------------------
     t1      | {orientation=row,enable_tde=on,encrypt_algo=AES_128_CTR,compression=no,storage_type=USTORE,key_type=...,dek_cipher=...

  3. 向加密表写入数据。

    操作加密表与非加密表的语法一致。数据库将表中数据写入磁盘前,才会自动对加密表的数据进行加密。
    gaussdb=# INSERT INTO t1 VALUES (1, 'tde plain 123');
    INSERT 0 1

  4. 从加密表查询数据。

    对于合法用户而言,查询加密表与非加密表的语法一致,加解密操作由数据库自动实现。如果攻击者绕过数据库,直接读取磁盘上加密表对应的数据文件,会发现文件中的数据均已被加密。
    gaussdb=# SELECT * FROM t1;
     c1 |      c2
    ----+---------------
      1 | tde plain 123
    (1 row)

  5. 轮转加密表的密钥。

    为提高安全性,建议定期使用以下语法轮转加密表的数据密钥,即使用新的密钥对数据进行加密。

    gaussdb=# ALTER TABLE t1 ENCRYPTION KEY ROTATION;
    ALTER TABLE

    轮转密钥后,数据库仍可以正常解密由旧密钥加密的数据。

  6. 加密表与非加密表转换。

    透明加密支持将加密表转换为非加密表,以及将非加密表转换为加密表。建议在每次转换后,手动执行VACUUM FULL tablename命令,以强制同步转换表中所有数据。

    gaussdb=# CREATE TABLE t3 (c1 INT, c2 TEXT);
    CREATE TABLE
    gaussdb=# ALTER TABLE t3 SET (enable_tde = on);
    ALTER TABLE
    gaussdb=# VACUUM FULL t3;
    VACUUM
    gaussdb=# ALTER TABLE t3 SET (enable_tde = off);
    ALTER TABLE
    gaussdb=# VACUUM FULL t3;
    VACUUM

  7. 删除加密表。

    gaussdb=# DROP TABLE IF EXISTS t1, t2, t3;
    DROP TABLE

操作加密索引

  1. 创建加密表。

    创建索引的基表,需确保基表也是加密表。
    gaussdb=# CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (enable_tde = on);
    CREATE TABLE

  2. 创建加密索引。

    与创建加密表的方式相同,通过在WITH子句中设置enable_tde=on参数,即将索引设置为加密索引。

    索引与基表使用相同的加密算法和密钥,对基表进行密钥轮转时,索引也会使用新密钥。

    gaussdb=# CREATE INDEX i1 ON t1(c2) WITH (enable_tde = on);
    CREATE INDEX

  3. 查看加密索引基本信息。

    与加密表一样,索引基本信息也存储在pg_class系统表中的reloptions字段中,索引的dek_cipher、encrypt_algo等参数与基表保持一致。

    gaussdb=# SELECT relname,reloptions FROM pg_class WHERE relname = 'i1';
     relname | reloptions
    ---------+-----------------------------------------------------------------------------------------------------------------------
     i1      | {orientation=row,enable_tde=on,encrypt_algo=AES_128_CTR,compression=no,storage_type=USTORE,key_type=...,dek_cipher=...

  4. 加密索引与非加密索引转换。

    透明加密支持将非加密索引转换为加密索引,将加密索引转换为非加密索引。

    gaussdb=# CREATE TABLE t2 (c1 INT, c2 TEXT) WITH (enable_tde = on);
    ALTER TABLE
    gaussdb=# CREATE INDEX i2 ON t2(c2);
    CREATE INDEX
    gaussdb=# ALTER INDEX i2 SET (enable_tde = on);
    ALTER INDEX
    gaussdb=# ALTER INDEX i2 SET (enable_tde = off);
    ALTER INDEX

  5. 自动对索引进行加密。

    默认情况下,主动设置enable_tde参数才可创建加密索引。当设置GUC参数tde_index_default_encrypt=on,且以加密表为基表创建索引时,数据库会自动将索引转换为加密索引。示例如下:

    gaussdb=# CREATE TABLE t3 (c1 INT, c2 TEXT) WITH (enable_tde = on);
    ALTER TABLE
    gaussdb=# CREATE INDEX i3 ON t3(c2);
    CREATE INDEX
    gaussdb=# SELECT relname,reloptions FROM pg_class WHERE relname = 'i3';
     relname | reloptions
    ---------+-----------------------------------------------------------------------------------------------------------------------
     i1      | {orientation=row,enable_tde=on,encrypt_algo=AES_128_CTR,compression=no,storage_type=USTORE,key_type=...,dek_cipher=...
    
    -- 解释:虽然未指定i3为加密索引,但是开启了tde_index_default_encrypt=on,且基表t3是加密表,数据库自动将i3转换为加密索引

  6. 删除加密表和索引。

    gaussdb=# DROP TABLE IF EXISTS t1, t2, t3;
    DROP TABLE

支持加密xlog和undo-log

  1. 创建TDE属性的表。

    gaussdb=# CREATE TABLE t1 (c1 INT, c2 TEXT) WITH (enable_tde = on);
    CREATE TABLE

  2. 记录xlog的写入位置。

    gaussdb=# SELECT pg_xlogfile_name_offset((SELECT pg_current_xlog_location()));
          pg_xlogfile_name_offset
    ------------------------------------
     (00000001000000000000000D,3121400)
    (1 row)

  3. 操作含TDE属性的表,生成携带数据的xlog。

    INSERT INTO t1 VALUES (1, 'sssssssssssssssss');

  4. 验证数据在xlog中已被加密。

    gaussdb=#  \! hexdump -C $DATADIR/pg_xlog/00000001000000000000000D -s 3121400 -n 2048
    002fa0f8  5e 00 00 80 01 00 00 00  00 00 00 00 00 00 00 00  |^...............|
    002fa108  d8 9c 2f 0d 00 00 00 00  e0 16 00 00 00 00 00 00  |../.............|
    002fa118  26 74 d4 9e ff 38 b8 17  00 00 00 00 00 00 d8 0e  |&t...8..........|
    002fa128  00 00 00 00 00 00 52 31  01 00 00 00 00 00 6b 26  |......R1......k&|
    002fa138  06 00 00 00 00 00 7a 33  01 00 00 00 00 00 7b 33  |......z3......{3|
    002fa148  01 00 00 00 00 00 f0 3d  2f 0d 00 00 00 00 00 00  |.......=/.......|
    002fa158  3e 00 00 80 01 00 00 00  ab 33 01 00 00 00 00 00  |>........3......|
    002fa168  f8 a0 2f 0d 00 00 00 00  80 16 00 00 00 00 00 00  |../.............|
    002fa178  14 79 79 89 ff 18 00 00  00 00 00 10 00 00 00 00  |.yy.............|
    002fa188  10 00 00 10 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    002fa198  3e 00 00 80 01 00 00 00  ab 33 01 00 00 00 00 00  |>........3......|
    002fa1a8  58 a1 2f 0d 00 00 00 00  b0 16 00 00 00 00 00 00  |X./.............|
    002fa1b8  6d 09 43 cc ff 18 00 00  00 00 00 10 00 00 00 80  |m.C.............|
    002fa1c8  00 00 00 10 00 00 00 00  00 00 00 00 00 00 00 00  |................|
    002fa1d8  13 02 00 80 01 00 00 00  ab 33 01 00 00 00 00 00  |.........3......|
    002fa1e8  98 a1 2f 0d 00 00 00 00  80 14 00 00 00 00 00 80  |../.............|
    002fa1f8  12 61 3e 44 40 60 1d 00  7f 06 00 00 13 32 00 00  |.a>D@`.......2..|
    002fa208  57 41 00 00 25 94 24 f9  f6 8d 46 50 8a f7 3f 92  |WA..%.$...FP..?.|
    002fa218  98 08 2c 57 a2 fc 16 3d  18 dc 6f 67 9e 8a c8 ba  |..,W...=..og....|
    002fa228  a3 7b 58 3f ba 50 d9 6c  52 d2 91 01 75 a7 a4 d9  |.{X?.P.lR...u...|
    002fa238  05 86 2d b1 10 aa 1c 46  14 7f 00 00 d3 3a 4a 22  |..-....F.....:J"|
    002fa248  e0 55 00 00 7f 06 00 00  09 00 00 01 00 35 a8 44  |.U...........5.D|
    002fa258  00 7f 00 00 00 00 00 00  00 00 00 00 00 00 00 00  |................|

  5. 删除t1表数据,生成undo-log,判断undo文件已被加密。

    预期:无法搜索到数据明文

    gaussdb=# DELETE FROM t1;
    DELETE 1
    grep -c 'ssssssssssssssssssssssss' $DATADIR/undo/permanent/*

  6. 删除加密表。

    gaussdb=# DROP TABLE IF EXISTS t1;
    DROP TABLE

相关文档