数据脱敏
数据脱敏,是指在保留数据原有格式的前提下,对某些敏感信息通过脱敏规则进行数据的变形或屏蔽,以防止未经授权的人员访问真实敏感数据的一种安全技术,从而实现敏感隐私数据的可靠保护。
数据脱敏主要分为静态脱敏和动态脱敏,静态数据脱敏采用”先脱敏-后分发”的方式,一般是将生产环境数据拷贝到测试或开发库中,导出后的数据已经改变了原始数据的内容,使得脱敏后的数据成为了测试开发源数据。而动态数据脱敏是与生产环境紧密关联的,访问敏感数据时实时地进行脱敏,主要用于直接访问生产数据的场景,在屏蔽敏感信息的同时也保证了源数据的一致性和有效性。
瀚高数据库主要提供动态数据脱敏功能。采用动态的改变来隐藏真实数据。通过给需要脱敏的每一个列定义一个函数来实现,返回脱敏函数处理后的数据给用户。数据脱敏只对用户数据做重编辑,不会对用户真实数据的传输、存储、非脱敏查询产生任何影响。
数据库安全员用户有权限打开脱敏开关,并创建、修改、删除、禁用、启用数据脱敏策略;关闭三权分立模块超级用户有权限打开脱敏开关,并创建、修改、删除、禁用、启用数据脱敏策略;
数据脱敏功能为V9.0.5版本新增功能。
数据脱敏的限制
瀚高数据库中对数据脱敏功能的运行做了以下限制:
数据脱敏目前仅支持对普通表、分区表、继承表配置脱敏策略,脱敏用户查询到的结果是脱敏后的值;
分区主表和每个分表、继承表都作为独立的表,需要单独创建脱敏策略。
一个列上创建了脱敏策略后,不允许该列做任何修改操作;
当 create table as 或 insert into
的数据来源于脱敏数据,则插入的数据为脱敏后的值,且无法还原。
不支持DELETE中的查询子句带有数据脱敏;
不支持MERGE INTO子句中带查询语句的数据脱敏。
数据脱敏插件
为使该模块生效,需要通过配置文件postgresql.conf
中的shared_preload_libraries
进行加载,给shared_preload_libraries参数追加hg_redaction,随后重启服务器。然后登录数据库管理员创建扩展:
[highgo@node1 bin]$ ./psql highgo highgo
用户 highgo 的口令:
psql (14.20)
hgdb-client-V9.0.5
输入 "help" 来获取帮助信息.
highgo=# create extension hg_redaction;
CREATE EXTENSION
|
脱敏开关
瀚高数据库中对数据脱敏模块设置了开关。数据脱敏功能打开时,数据脱敏才会生效。数据脱敏功能关闭时,数据库不会发生数据动态脱敏动作。
hg_redaction.enable为设置数据脱敏功能是否开启的总开关,取值为on和off,缺省为off。
on表示打开数据脱敏功能;
off表示关闭数据脱敏功能;
在会话中可以用SET的方式设置开关立即生效,也可以使用ALTER SYSTEM
SET的方式,重载或重启数据库生效。
在瀚高数据库启动之前,修改postgresql.conf文件,将hg_redaction.enable参数设置为on或off。
在瀚高数据库启动之后,通过SQL命令修改:
SET hg_redaction.enable=on;--立即生效
或
|
ALTER SYSTEM SET hg_redaction.enable=on;
SELECT pg_reload_conf();--重载生效
|
创建脱敏策略
支持通过使用 CREATE REDACTION POLICY
的语法来创建脱敏策略。一张表上支持创建多个数据脱敏策略,但是每个列上只允许创建一次;支持在不同的表上创建同名的策略。
需要注意的是:如果给用户U1创建的脱敏策略,然后将U1用户重新命名成U2,那么U1的脱敏策略不会对U2生效。
创建脱敏策略的语法:
CREATE REDACTION POLICY <name> ON <schema.tbname>
[ FOR ( <expression>[,...] ) ]
ADD [COLUMN] <column_name>[,...] USING <funcname_clause>
[ WITH OPTIONS ( [ <redaction_option> ]
[, <redaction_option> ] )
]
[, ...]
[ENABLE | DISABLE]
|
参数说明
修改脱敏策略
支持更改脱敏策略的相关信息,可以修改脱敏策略的名称,表达式,脱敏函数,增加/删除脱敏列和修改脱敏列属性,可以单独开启和关闭某一个数据脱敏策略。
修改脱敏策略的语法有如下几种:
方式一:
ALTER REDACTION POLICY <name> ON <schema.tbname> RENAME TO <new_name>;
|
参数说明
name
数据脱敏策略的名称
schema.tbname
需要建立脱敏策略的表名
new_name
数据脱敏策略的新名称
方式二:
ALTER REDACTION POLICY <name> ON <schema.tbname> FOR ( <expression> );
|
参数说明
方式三:
ALTER REDACTION POLICY <name> ON <schema.tbname>
ADD [ COLUMN ] <column_name>[,...] USING <funcname_clause>
[ WITH OPTIONS ( [ <redaction_option> ]
[, <redaction_option> ] )
]
[,...];
|
参数说明
name
数据脱敏策略的名称
schema.tbname
需要建立脱敏策略的表名
column_name
列名
funcname_clause
函数名
redaction_option
SCOPE(query, top_tlist, top_tlist_or_error)
query表示无论出现在查询中的什么位置,都会对列应用脱敏;缺省为query
top_tlist表示仅当列出现查询在顶部目标列中时,才对列应用脱敏;
top_tlist_or_error行为与top_list相同,但当该列出现在查询中的其他任何地方会抛出一个错误。
EXCEPTION(none, equal)
none 表示没有exception;
equal 表示在等式查询中,脱敏列不脱敏。缺省为equal。
方式四:
ALTER REDACTION POLICY <name> ON <schema.tbname>
DROP [ COLUMN ] <column_name>;
|
参数说明
name
数据脱敏策略的名称
schema.tbname
需要建立脱敏策略的表名
column_name
列名
方式五:
ALTER REDACTION POLICY <name> ON <schema.tbname>
MODIFY [ COLUMN ]
{
<column_name> [, ...]
[ USING <funcname_clause> ]
|
[ WITH OPTIONS ( [ <redaction_option> ]
[, <redaction_option> ] )
]
}
{, ...}
|
参数说明
Name
数据脱敏策略的名称
schema.tbname
需要建立脱敏策略的表名
column_name
列名
funcname_clause
函数名
redaction_option
- SCOPE(query, top_tlist, top_tlist_or_error)
query表示无论出现在查询中的什么位置,都会对列应用脱敏;缺省为query
top_tlist表示仅当列出现查询在顶部目标列中时,才对列应用脱敏;
top_tlist_or_error行为与top_list相同,但当该列出现在查询中的其他任何地方会抛出一个错误。
none 表示没有exception;
equal 表示在等式查询中,脱敏列不脱敏。缺省为equal。
方式六:
ALTER REDACTION POLICY <name> ON <schema.tbname> [ENABLE | DISABLE];
|
参数说明
name
数据脱敏策略的名称
schema.tbname
需要建立脱敏策略的表名
删除脱敏策略
删除数据脱敏策略后,数据脱敏策略相关信息将从表
hg_security.hg_redaction_policy和
hg_security.hg_redaction_column中一并删除。删除用户表时,如果用户表上有数据脱敏策略,那么该表上的脱敏策略将一并删除。
删除脱敏策略的语法:
DROP REDACTION POLICY [ IF EXISTS ] <name> ON <schema.tbname> [ CASCADE | RESTRICT ]
|
参数说明
name
数据脱敏策略的名称
schema.tbname
需要建立脱敏策略的表名
查看脱敏策略
提供hg_security.hg_redaction视图,用于查询已创建的脱敏策略,数据库安全员或超级用户有权限查看所有脱敏策略。
数据脱敏函数与特性
数据脱敏功能通过使用脱敏函数来实现,瀚高数据库支持完整脱敏、部分数据脱敏、数据脱敏、邮件数据脱敏和随机数据脱敏等多种脱敏函数。用户可结合对应的脱敏策略使用数据库脱敏函数。
| 函数 |
支持的数据类型 |
说明 |
| hg_security.redact_all |
BOOL,TIME,TIMETZ,INTERVAL,TIMESTAMP,TIMESTAMPTZ,TEXT,BPCHAR,VARCHAR ,NAME, INT8,INT4,INT2,NUMRIC,FLOAT4,FLOAT8, MONEY,SECLABEL |
‘4880-9898-4545-2525’ 将会被脱敏为 ‘xxxxxxxxxxxxxxxxxxx’,安全标签的被脱敏为’s*****’ |
| hg_security.redact_bankcard |
BPCHAR, VARCHAR, TEXT( 注: 仅针对信用卡格式的文本类数据) |
‘4880-9898-4545-2525’ 将会被脱敏为 ‘xxxx-xxxx-xxxx-2525’, 该函数仅对后 4 位之前的数字进行脱敏。 |
| hg_security.redact_emailname |
BPCHAR, VARCHAR, TEXT (注: 仅针对 email格式的文本类型数据) |
‘abcd@gmail.com‘ 将会被脱敏为‘xxxx@gmail.com‘, 对出现第一个‘@’之前的文本进行脱敏 |
| hg_security.redact_emailfull |
BPCHAR, VARCHAR, TEXT (注: 仅针对 email格式的文本类型数据) |
‘abcd@gmail.com‘ 将会被脱敏为‘xxxx@xxxxx.com‘, 对出现最后一个’.’之前的文本( 除‘@’符外) 进行脱敏 |
| hg_security.redact_digits |
BPCHAR, VARCHAR, TEXT (注: 仅针对包含数字的文本类型数据) |
‘alex123alex’ 将会被脱敏为’alex000alex’, 仅对文本中的数字进行脱敏。 |
| hg_security.redact_shuffle |
BPCHAR, VARCHAR, TEXT (注: 仅针对文本类型数据) |
‘hello word’ 将会被随机打乱顺序脱敏为 ‘hlwoeor dl’, 该函数通过字符乱序排列的方式实现, 属于弱脱敏函数, 语义较强的字符串不建议使用该函数脱敏。 |
| hg_security.redact_random |
BPCHAR, VARCHAR, TEXT (注: 仅针对文本类型数据) |
‘hello word’ 将会被脱敏为’ad5f5ghdf5’, 将文本按字符随机脱敏 |
| hg_security.redact_idcard |
BPCHAR,VARCHAR, TEXT(注: 仅针对身份证格式的文本类型数据) |
对身份证号进行脱敏130623202101010623’将被脱敏为’130623*******0623’, 该函数保留身份证号的前六位和后四位,中间的号码用代替。 |
| hg_security.redact_name |
BPCHAR, VARCHAR, TEXT (注: 仅针对姓名的文本类型数据) |
对姓名进行脱敏。不管名字是几个字, 保留第一个字, 后面两个*表示。如“张三”被脱敏为“张”, “张三丰”被脱敏为“张”, “富兰克林”被脱敏为“富**” |
| hg_security.redact_phone |
BPCHAR, VARCHAR, TEXT (注: 仅针对电话号码的文本类型数据) |
对电话号码进行脱敏。适用于手机号和固话号。保留前三位和后四位, 对中间数字进行脱敏。如“13534556093” 脱敏为“135*6093”“053*0980”。备注:中间有多少个字符显示多少个。 |
| hg_security.redact_cash |
MONEY |
对货币类型进行脱敏处理,如“100.00” 会脱敏成“¥0.00”或“$0.00 |
数据脱敏的使用
一、启用数据脱敏功能
在数据库启动之前,修改配置文件postgresql.conf,给shared_preload_libraries参数追加hg_redaction,随后启动数据库。
登录数据库管理员用户创建扩展
[highgo@node1 bin]$ ./psql highgo highgo
用户 highgo 的口令:
psql (14.20)
hgdb-client-V9.0.5
输入 "help" 来获取帮助信息.
highgo=# create extension hg_redaction;
CREATE EXTENSION
打开脱敏开关
highgo=# \c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> SET hg_redaction.enable=on;
SET
|
二、创建一个完整脱敏策略
登录highgo用户创建测试用户
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=# create user u1 password 'highgo';
CREATE ROLE
highgo=# create user u2 password 'highgo';
CREATE ROLE
highgo=# create user u3 password 'highgo';
在用户u3下创建测试表,并赋予u1和u2用户select权限
highgo=# \c highgo u3
用户 u3 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u3".
highgo=> create table test(id int, col1 varchar,info text);
CREATE TABLE
highgo=> insert into test values(1,'highgo','database');
INSERT 0 1
highgo=> insert into test values(2,'postgres','opensource');
INSERT 0 1
highgo=> grant select on test to u1,u2;
GRANT
登录安全员用户创建完整脱敏策略,仅对u1用户生效
highgo=> c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> create redaction policy p1 on test for(user='u1') add column col1 using hg_security.redact_all;
CREATE REDACTION POLICY
登录u1用户查看test表中col1列数据已完全脱敏
highgo=> c highgo u1
用户 u1 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u1".
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | xxxxxx | database
2 | xxxxxxxx | opensource
(2 行记录)
登录u2用户查看test表完整数据
highgo=> c highgo u2
用户 u2 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u2".
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | highgo | database
2 | postgres | opensource
(2 行记录)
|
三、修改脱敏策略,将test表中info列进行随机脱敏显示
登录安全员用户修改脱敏策略
highgo=> c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> alter redaction policy p1 on test add column info using hg_security.redact_random;
ALTER REDACTION POLICY
验证info列对u1用户脱敏,对u2用户正常显示
highgo=> c highgo u1
用户 u1 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u1".
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | xxxxxx | cef1b1eb
2 | xxxxxxxx | 120342a72c
(2 行记录)
highgo=> c highgo u2
用户 u2 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u2".
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | highgo | database
2 | postgres | opensource
(2 行记录)
|
四、创建test2表,在多个列上添加不同的脱敏规则
对test2表中的2列数据添加不同的脱敏规则
[highgo@node1 bin]$ ./psql highgo highgo
用户 highgo 的口令:
psql (14.20)
hgdb-client-V9.0.5
输入 "help" 来获取帮助信息.
highgo=# select * from test2;
name | phone | idcard | money
----------+-------------+--------------------+---------
富兰克林 | 15789177109 | 130623202101010623 | $500.00
(1 行记录)
highgo=# \c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> create redaction policy p2 on test2 add name using hg_security.redact_name,add phone using hg_security.redact_phone;
CREATE REDACTION POLICY
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=# select * from test2;
name | phone | idcard | money
------+-------------+--------------------+---------
富** | 157****7109 | 130623202101010623 | $500.00
|
2.删除脱敏策略
highgo=> drop redaction policy p2 on test2;
DROP REDACTION POLICY
|
五、创建脱敏策略,等式查询中脱敏列不脱敏
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=# create table test3(id int, name text);
CREATE TABLE
highgo=# insert into test3 values(1, 'zhangsan');
INSERT 0 1
highgo=# \c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> create redaction policy p3 on test3 add column name using hg_security.redact_all with options(scope query, exception equal);
CREATE REDACTION POLICY
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=#
highgo=# select * from test3;
id | name
----+----------
1 | xxxxxxxx
(1 行记录)
----等式查询中name列不脱敏,能匹配到test3表里存的数据,所以有一条返回数据,返回为脱敏后的数据。
highgo=# select * from test3 where name = 'zhangsan';
id | name
----+----------
1 | xxxxxxxx
(1 行记录)
highgo=# \c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> drop redaction policy p3 on test3;
DROP REDACTION POLICY
highgo=> create redaction policy p4 on test3 add column name using hg_security.redact_all with options(scope query, exception none);
CREATE REDACTION POLICY
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
--无返回数据
highgo=# select * from test3 where name = 'zhangsan';
id | name
----+------
(0 行记录)
--有返回数据
highgo=# select * from test3 where name = 'xxxxxxxx';
id | name
----+----------
1 | xxxxxxxx
(1 行记录)
highgo=> c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=>
highgo=> drop redaction policy p4 on test3;
DROP REDACTION POLICY
|
六、创建脱敏策略,top_tlist
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=# create table tb1(id int4 primary key,info text,name varchar);
highgo=#create table tb2(id int4,info text,name varchar);
highgo=#insert into tb1 values(1,'hgdb','highgo'),(2,'student','zhang'),(3,'fruit','apple');
highgo=#insert into tb2 values(1,'hgdb','highgo'),(22,'student','zhang'),(33,'fruit','apple');
highgo=#
highgo=# \c highgo syssso
用户 syssso 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "syssso".
highgo=> create redaction policy tb1_pol1 on tb1 add column id using hg_security.redact_all with options (scope top_tlist);
CREATE REDACTION POLICY
--查询tb1表发现id列已被脱敏
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=#
highgo=# select * from tb1;
id | info | name
----+---------+--------
0 | hgdb | highgo
0 | student | zhang
0 | fruit | apple
(3 行记录)
--redaction option为scope toplist,仅当列出现查询在顶部目标列中时,才对列应用脱敏,出现在子查询中不会脱敏。
highgo=# SELECT id,name FROM tb2 WHERE id = (SELECT min(id) FROM tb1 WHERE name = 'highgo');
id | name
----+--------
1 | highgo
(1 行记录)
|
脱敏数据的导出导入
对表添加数据脱敏策略后,不会影响数据的导入导出操作。
1.u1用户登录数据库,查看test表
highgo=> c highgo u1
用户 u1 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u1".
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | xxxxxx | 7ee15b47
2 | xxxxxxxx | 6a36652c3c
(2 行记录)
2.将test表数据指定输出到当前客户端
highgo=> copy test to stdout with csv;
1,highgo,database
2,postgres,opensource
3.使用highgo用户登录,将test表导出到csv文件
highgo=> c highgo highgo
用户 highgo 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "highgo".
highgo=# copy test to '/home/highgo/test' with csv;
COPY 2
4.查看导出的文件
[highgo@node1 ~]$ cat /home/highgo/test
1,highgo,database
2,postgres,opensource
5.highgo用户登录,将导出数据导入到test表
[highgo@node1 bin]$ ./psql highgo highgo
用户 highgo 的口令:
psql (14.20)
hgdb-client-V9.0.5
输入 "help" 来获取帮助信息.
highgo=# copy test from '/home/highgo/test' (FORMAT 'csv', DELIMITER ','); COPY 2
highgo=#
highgo=# select * from test;
id | col1 | info
----+----------+------------
1 | highgo | database
2 | postgres | opensource
1 | highgo | database
2 | postgres | opensource
(4 行记录)
|
脱敏数据的备份恢复
对表添加数据脱敏策略后,不会影响数据的备份和恢复操作。
1.备份已添加脱敏策略的test表
[highgo@node1 bin]$ ./pg_dump -f /home/highgo/testdump -Fc -t test highgo
2.登录u3用户删除test表,注意:表对象删除后会同步删除脱敏策略。
[highgo@node1 bin]$ ./psql highgo u3
用户 u3 的口令:
psql (14.20)
hgdb-client-V9.0.5
输入 "help" 来获取帮助信息.
highgo=> drop table test;
DROP TABLE
3.执行恢复操作
[highgo@node1 bin]$ ./pg_restore -U u3 -d highgo /home/highgo/testdump
4.登录u3用户检查数据是否恢复
[highgo@node1 bin]$ ./psql highgo u3
用户 u3 的口令:
psql (14.20)
hgdb-client-V9.0.5
输入 "help" 来获取帮助信息.
highgo=> dt
关联列表
架构模式 | 名称 | 类型 | 拥有者
----------+-------+--------+--------
public | test | 数据表 | u3
public | test2 | 数据表 | u3
(2 行记录)
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | highgo | database
2 | postgres | opensource
1 | highgo | database
2 | postgres | opensource
(4 行记录)
5.登录u1用户,查询test表
highgo=> c - highgo u1
无法解释主机名 "u1" 到地址: 未知的名称或服务
保留上一次连接
highgo=> c highgo u1
用户 u1 的口令:
hgdb-client-V9.0.5
您现在已经连接到数据库 "highgo",用户 "u1".
highgo=> select * from test;
id | col1 | info
----+----------+------------
1 | highgo | database
2 | postgres | opensource
1 | highgo | database
2 | postgres | opensource
(4 行记录)
|