敏感字段加密(rds_encdb)

更新时间:2025-03-21 09:31:25

RDS PostgreSQL提供了rds_encdb插件,用于对查询结果集的敏感列进行加密。同时,通过对数据库账户权限进行设置,相关账户在访问敏感列信息时,仅能获得密文格式的查询结果。

您可以加入RDS PostgreSQL插件交流钉钉群(103525002795),进行咨询、交流和反馈,获取更多关于插件的信息。

前提条件

  • 实例大版本为RDS PostgreSQL 16。

  • 实例内核小版本为20250228及以上。

    如需升级内核小版本,请参见升级内核小版本

应用场景

rds_encdb插件适用于需要对查询结果进行动态脱敏的场景,尤其适合金融、医疗和电商等高敏感数据行业。例如:

  • 数据动态加密场景

  • 合规审计场景

  • 第三方数据共享场景

通过使用该插件,您无需修改业务代码即可实现结果集级加密,从而在保证查询效率的同时维护数据隐私。

使用限制

当前暂不支持以下SQL特性:

  • 函数返回的查询结果集。

  • SELECT类型查询,例如游标操作、prepare/execute语句。

  • CTEUNION子句。

安装插件

重要

开通列加密功能时,系统将默认在目标数据库中安装rds_encdb插件。目前尚不支持在目标数据库中手动直接安装该插件。如需进行自主安装,请联系我们

  1. 设置实例参数,将rds_encdb.enable_encryption运行参数值改为on

  2. 请使用高权限账号连接目标数据库,并执行以下SQL安装rds_encdb插件。如需创建高权限账号,请参见创建账号

    CREATE EXTENSION rds_encdb;
    说明

    执行SELECT * FROM pg_extension;可以查看已安装的插件。

设置列加密策略

rds_encdb插件通过元数据表rds_encdb.encryption_rule来记录需要加密的列。如需对某一列数据启用加密,只需向该表中插入相应的记录。此后,针对该列的查询将以密文格式返回,并且此设置对现有会话同样有效。

rds_encdb.encryption_rule表结构

列名

类型

说明

列名

类型

说明

id

int

主键,自增ID。

rule_name

name

表示该加密规则的名称。

attrelid

regclass

该加密规则对应的表,需满足 (rule_name, attrelid, attnum) 的唯一约束。

attnum

smallint

该加密规则对应的原表中列的序号。

加密算法

默认的加密算法为AES_256_GCM。

设置示例

  1. 创建测试表,并插入测试数据。

    CREATE TABLE test(a text,b text,c text);
    
    INSERT INTO test VALUES ('foo','bar','hello world');
  2. 查询测试表中的数据,此时返回的结果为明文。

    SELECT * FROM test;

    返回结果:

      a  |  b  |      c
    -----+-----+-------------
     foo | bar | hello world
    (1 row)
  3. 向元数据表rds_encdb.encryption_rule插入一条记录,以对test表的第1列和第2列进行加密。

    INSERT INTO rds_encdb.encryption_rule 
    VALUES 
        (9, 'rule1', 'test', '1'), 
        (10, 'rule1', 'test', '2');
  4. 查询测试表中的数据,此时返回的结果为密文。

    SELECT * FROM test;

    返回结果:

                                    a                                 |                                b                                 |      c
    ------------------------------------------------------------------+------------------------------------------------------------------+-------------
     1yAZAAAACVyTxvBACK5JFw0w/ZU62Yt9btkv9bSN8TcJWOfXCiWVnCqnakSZCwI= | DSAZAAAACaSrnhi0usv3MiJsgRQKXA5xEArdALSdnFVjqD0nrd1s6ilShhw00EM= | hello world
    (1 row)
  5. 在元数据表rds_encdb.encryption_rule中查看已设置的加密规则。

    SELECT * FROM rds_encdb.encryption_rule;

    返回结果:

     id | rule_name | attrelid | attnum
    ----+-----------+----------+--------
      9 | rule1     | test     |      1
     10 | rule1     | test     |      2
    (2 rows)

rds_encdb插件提供了一张视图,通过执行以下SQL,可以将设置的加密规则记录以(规则名称,表名)方式进行聚合。

SELECT * FROM rds_encdb.rules;

例如:

 rule_name | attrelid | attname_list
-----------+----------+--------------
 rule1     | test     | b,a
(1 row)

设置账号加密列权限

可以为目标账号设置以下加密列权限,若未进行设置,则默认为RESTRICTED ACCESS权限。

账号权限

说明

账号权限

说明

FULL ACCESS

完全访问加密列权限。具备该权限的账号进行查询时,返回结果中的加密列将以明文形式呈现。

RESTRICTED ACCESS

限制访问加密列权限。具备该权限的账号进行查询时,返回结果中的加密列将以密文形式呈现。使用encjdbc方式访问时,返回结果中的加密列将以明文形式呈现。

设置账号加密列权限

SELECT rds_encdb.setup_encryption_role('账号', '加密列权限', '过期时间');

取消账号加密列权限

SELECT rds_encdb.remove_encryption_role('账号');

已设置加密列权限的账号将记录在rds_encdb插件的元数据表rds_encdb.setup_encryption_role中。该表的结构如下:

列名

类型

说明

列名

类型

说明

role

regrole

主键,表示该加密权限对应的用户名。

role_type

char

账号的加密列权限:

  • rRESTRICTED ACCESS

  • fFULL ACCESS。

salt

text

账号对应的密钥。使用encjdbc方式访问时,客户端在建立连接后会自行设置并生成。

expire_time

timestamptz

账号加密列权限的过期时间。超过配置时间后,加密列权限将会变更为RESTRICTED ACCESS

格式为:YYYY-MM-DD HH:MM:SS.ssssss+/-TZ

设置示例

  1. 为目标账号设置加密列权限。

    SELECT rds_encdb.setup_encryption_role('test_user','FULL ACCESS',now());
  2. 查看已经设置加密列权限的账号。

    SELECT * FROM rds_encdb.encryption_role_auth;

    返回结果:

       role    | role_type | salt |          expire_time
    -----------+-----------+------+-------------------------------
     rds_test | f         |      | 2025-02-21 06:01:02.509447+00
    (1 row)

  • 本页导读
  • 前提条件
  • 应用场景
  • 使用限制
  • 安装插件
  • 设置列加密策略
  • 设置账号加密列权限