乐趣区

关于数据仓库:你应该知道的数仓安全

摘要:避免数据泄露能够有两种技术门路。一是权限治理,采纳最小化受权准则对应用数据的用户和应用程序受权。另一种是数据加密,包含应用 SQL 函数加密和通明加密。

本文分享自华为云社区《【平安无小事】你应该晓得的数仓平安——加密函数》,原文作者:zhangkunhn。

前言

最近遇到一个客户场景,波及共享 schema 的权限问题。场景简略能够形容为:一些用户是数据的生产方,须要在 schema 中创立表并写入数据;另一些用户是数据的生产方,读取 schema 中的数据做剖析。对于该 schema 权限治理的一种实现办法是数据生产方在每次创立新表后告知管理员用户应用 grant select on all tables in schema 语法来授予生产方权限。这种办法有肯定的局限性。如果生产方在 schema 上面又创立了一些新表,为了受权生产方应用这些新表还须要告知管理员用户再次应用 grant select on all tables in schema 来受权。有没有简略的应答计划?答案是必定的,能够应用 Alter default privilege。Alter default privilege 用于未来创立的对象的权限的授予或回收。

语法介绍

 ALTER DEFAULT PRIVILEGES
     [FOR { ROLE | USER} target_role [, ...] ]
     [IN SCHEMA schema_name [, ...] ]
     abbreviated_grant_or_revoke;

其中 abbreviated_grant_or_revoke 子句用于指定对哪些对象进行受权或回收权限。对表受权语法是:

 GRANT {{ SELECT | INSERT | UPDATE | DELETE | TRUNCATE | REFERENCES} 
     [, ...] | ALL [PRIVILEGES] }
     ON TABLES 
     TO {[ GROUP] role_name | PUBLIC } [, ...]

参数阐明

  • target_role

已有角色的名称。如果省略 FOR ROLE/USER,则缺省值为以后角色 / 用户。

取值范畴:已有角色的名称。

  • schema_name

现有模式的名称。

target_role 必须有 schema_name 的 CREATE 权限。

取值范畴:现有模式的名称。

  • role_name

被授予或者勾销权限角色的名称。

取值范畴:已存在的角色名称。

详见 ALTER DEFAULT PRIVILEGES 语法阐明

场景示例

testdb=# create user creator1 password 'Gauss_234';  
 CREATE USER
 testdb=# create user creator2 password 'Gauss_234';  
 CREATE ROLE
 testdb=# create user user1 password 'Gauss_234';
 CREATE USER
 -- 创立共享 schema,授予 creator1 和 creator2 创立权限,授予 user1 应用权限
 testdb=# create schema shared_schema;  
 CREATE SCHEMA
 testdb=> grant create, usage on schema shared_schema to creator1;
 GRANT
 testdb=> grant create, usage on schema shared_schema to creator2;
 GRANT
 testdb=# grant usage on schema shared_schema to user1;
 GRANT
 -- 将 creator1 和 creator2 在 shared_schema 中创立表的 select 权限授予 user1
 testdb=# alter default privileges for user creator1, creator2 in schema shared_schema grant select on tables to user1;
 ALTER DEFAULT PRIVILEGES
 -- 切到 creator1,建表
 testdb=# \c testdb creator1
 You are now connected to database "testdb" as user "creator1".
 testdb=> create table shared_schema.t1 (c1 int);
 CREATE TABLE
 -- 切到 creator2,建表
 testdb=> \c testdb creator2
 You are now connected to database "testdb" as user "creator2".
 testdb=> create table shared_schema.t2 (c1 int);
 CREATE TABLE
 -- 切到 user1,查问 OK
 testdb=> \c testdb user1
 You are now connected to database "testdb" as user "user1".
 testdb=> select * from shared_schema.t1 union select * from shared_schema.t2;
  c1 
 ----
 (0 rows)

查看默认权限的授予现状

查问零碎表 pg_default_acl 能够查看以后哪些 schema 被授予了默认权限。从 defaclacl 字段能够看到 creator1 和 creator2 别离授予了 user1 对 shared_schema 中对象的 select 权限(r 示意 read)。

 testdb=# select r.rolname, n.nspname, a.defaclobjtype, a.defaclacl from
 testdb-#     pg_default_acl a, pg_roles r, pg_namespace n
 testdb-#     where a.defaclrole=r.oid and a.defaclnamespace=n.oid;
  rolname  |    nspname    | defaclobjtype |     defaclacl      
 ----------+---------------+---------------+--------------------
  creator1 | shared_schema | r             | {user1=r/creator1}
  creator2 | shared_schema | r             | {user1=r/creator2}
 (2 rows)

一些细节

所有在共享 schema 中创建对象的用户都应该呈现在 alter default privileges for user 之后的列表中。否则,如果有用户 creator3 没有在列表中,其在共享 schema 中创立的对象或者说那些 Owner 是 creator3 的对象将不能被 user1 查问。因为共享 schema 中 creator3 用户创立的表没有授予 user1 默认权限。

testdb=# create user creator3 password 'Gauss_234';
 CREATE USER
 testdb=# grant create, usage on schema shared_schema to creator3;
 GRANT
 testdb=# \c testdb creator3
 You are now connected to database "testdb" as user "creator3".
 testdb=> create table shared_schema.t3 (c1 int);
 CREATE TABLE
 testdb=> \c testdb user1
 You are now connected to database "testdb" as user "user1".
 testdb=> select * from shared_schema.t3;
 ERROR:  permission denied for relation t3

管理员能够通过 alter default privileges for user 将 creator3 放入列表中为 user1 授予拜访 creator3 用户创立表的默认权限,也能够由 creator3 用户本人通过 alter default privileges 受权给 user1. 后面语法参数阐明中有如果省略 FOR ROLE/USER,则缺省值为以后用户。

testdb=> \c testdb creator3
 You are now connected to database "testdb" as user "creator3".
 testdb=> alter default privileges in schema shared_schema grant select on tables to user1;
 ALTER DEFAULT PRIVILEGES
 testdb=> \c testdb user1
 You are now connected to database "testdb" as user "user1".
 testdb=> select * from shared_schema.t3;
 ERROR:  permission denied for relation t3
 testdb=> \c testdb creator3
 testdb=> create table shared_schema.t4 (c1 int);
 CREATE TABLE
 testdb=> \c testdb user1
 You are now connected to database "testdb" as user "user1".
 testdb=> select * from shared_schema.t4;
  c1 
 ----
 (0 rows)

上述代码第 3 行为以后用户在 shared_schema 上面创立的表的 select 权限授予 user1。第 7 行 user1 查问 shared_schema.t3 报权限有余,是因为 alter default privileges 只解决未来的对象。shared_schema.t3 在是之前创立的。咱们新建表 shared_schema.t4,user1 用户查问失常。

如果要解决已有表的权限,应用 grant 语句。参见 grant 语法阐明。

testdb=> \c testdb creator3
 You are now connected to database "testdb" as user "creator3".
 testdb=> grant select on all tables in schema shared_schema to user1;
 ERROR:  permission denied for relation t1
 testdb=> grant select on table shared_schema.t3 to user1;
 GRANT
 testdb=> \c testdb user1
 You are now connected to database "testdb" as user "user1".
 testdb=> select * from shared_schema.t3;
  c1 
 ----
 (0 rows)

代码第 3 行中 shared_schema 中蕴含有 3 个用户创立的表,而 creator3 只是表 t3 的创建者(Owner)。所以授予整个 schema 的权限会报错,只授予 creator3 是 Owner 的表 t3 之后,user1 用户查问失常。

alter default privileges 只解决未来的对象,grant 只解决已有的对象。进一步的,这两种语法授予权限时波及的对象仅包含 Owner 是以后用户的对象。如果要为共享 schema 上面所有 Owner 的对象授予权限,须要应用管理员用户应用 alter default privileges for user 语法和 grant 语法。

通明加密

通明加密的利用场景

通明加密可能保障用户数据安全。更换磁盘、磁盘流出或者运维非法间接读取磁盘文件会绕过认证、权限治理和审计,从而导致数据泄露的危险。客户对业务数据有很高机密性要求时倡议应用通明加密。

通明加密的原理

通明加密性能是对存在硬盘上的用户数据加密存储,对用户及下层应用 SQL 的利用不感知。通明的含意是指对客户来说是无感知的,仅须要创立 GaussDB(DWS)集群时配置通明加密。目前反对行存表和列存表文件的加密存储,反对集群级别的通明加密配置。

集群级别的通明加密意味着集群中的所有库,库中的所有表都是加密存储。集群级别的通明加密还意味着须要在创立集群时进行配置,集群创立之后不可批改,既不能将非加密集群批改为加密集群,也不能将加密集群批改为非加密集群。

加密算法

通明加密外围是算法和密钥。咱们采纳 AES-128 算法,加密模式应用 CTR。CTR 流加密能够保障明文和密文长度相等,不会导致加密后数据存储空间收缩。

密钥治理

应用华为私有云 KMS 服务治理,保障了用户的密钥平安。
加密密钥层次结构有三层。按层次结构顺序排列,这些密钥为主密钥(CMK)、集群密钥 (CEK)、数据库密钥 (DEK)。

  • 主密钥保留在 KMS 中,用于给 CEK 加密。
  • CEK 用于加密 DEK,CEK 明文保留在集群内存中,密文保留在服务治理面中。
  • DEK 用于加密数据库中的数据,DEK 明文保留在集群内存中,密文保留在服务治理面中。

密钥轮转

出于平安思考,用户能够执行密钥轮转操作。密钥轮转只轮转集群密钥,不管转数据库秘钥。

通明加密的后续演进

集群级通明加密的长处是所有数据包含用户表和零碎表都加密,实用于所有加密需要。一枚硬币的两面性通知咱们,长处也可能是毛病。对所有数据库对象加密会对数据导入和查问带来性能上的开销。

为解决此问题,后续思考反对细粒度通明加密。比方能够反对表级通明加密,用户在创立表时指定属性为加密表,该用户表的数据会加密存储。用户能够在蕴含敏感数据的表中开启加密属性,在查问和应用过程中不感知加解密过程。因为加密粒度较小,对性能的影响也较小。

通明加密是保障用户外围数据安全的无效伎俩。从应用场景和原理介绍了 GaussDB(DWS)数仓的通明加密个性,指出了后续通明加密个性的钻研方向。

SQL 函数加密

技术背景

密码学中明码算法能够分为三类:哈希函数、对称明码算法和非对称明码算法。

  • 哈希函数

哈希函数又称为摘要算法,对于数据 data,Hash 函数会生成固定长度的数据,即 Hash(data)=result。这个过程是不可逆的,即 Hash 函数不存在反函数,无奈由 result 失去 data。在不应保留明文场景,比方口令 (password) 属于敏感信息,系统管理员用户也不应该晓得用户的明文口令,就应该应用哈希算法,存储口令的单向哈希值。

理论应用中会退出盐值和迭代次数,防止雷同口令生成雷同的哈希值,以避免彩虹表攻打。

  • 对称明码算法

对称明码算法应用雷同的密钥来加密和解密数据。对称明码算法分为分组明码算法和流明码算法。

分组明码算法将明文分成固定长度的分组,用密钥对每个分组加密。因为分组长度固定,当明文长度不是分组长度的整数倍时,会对明文做填充解决。因为填充的存在,分组明码算法失去的密文长度会大于明文长度。

流明码算法将明文逐比特与密钥流运算。流明码算法不须要填充,失去的密文长度等于明文长度。

  • 非对称明码算法

非对称明码算法,又称为公钥明码算法。算法应用两个密钥:公钥和私钥。公钥向所有人公开,私钥窃密。非对称明码算法利用于密钥协商、数字签名、数字证书等畛域。

技术实现

GaussDB(DWS)次要提供了哈希函数和对称明码算法。哈希函数反对 sha256, sha384, sha512 和国密 sm3。对称明码算法反对 aes128, aes192, aes256 和国密 sm4。

哈希函数

  • md5(string)

将 string 应用 MD5 加密,并以 16 进制数作为返回值。MD5 的安全性较低,不倡议应用。

  • gs_hash(hashstr, hashmethod)

以 hashmethod 算法对 hashstr 字符串进行信息摘要,返回信息摘要字符串。反对的 hashmethod:sha256, sha384, sha512, sm3。

testdb=# SELECT gs_hash('GaussDB(DWS)', 'sha256');
                             gs_hash                              
------------------------------------------------------------------
 cc2d1b97c6adfba44bbce7386516f63f16fc6e6a10bd938861d3aba501ac8aab
(1 row)

对称明码算法

  • gs_encrypt(encryptstr, keystr, cryptotype, cryptomode, hashmethod)
    采纳 cryptotype 和 cryptomode 组成的加密算法以及 hashmethod 指定的 HMAC 算法,以 keystr 为密钥对 encryptstr 字符串进行加密,返回加密后的字符串。
    反对的 cryptotype:aes128, aes192, aes256, sm4。
    反对的 cryptomode:cbc。
    反对的 hashmethod:sha256, sha384, sha512, sm3。
testdb=# SELECT gs_encrypt('GaussDB(DWS)', '1234', 'aes128', 'cbc',  'sha256');
                                                        gs_encrypt                                                        
--------------------------------------------------------------------------------------------------------------------------
 AAAAAAAAAADlzZYiNQK1uB+p1gza4Lu3Moj3HdP4E1uJmqfDYBaXDLMt7RZoE0YVx9h2dMRYBQ5fhFNqqM49sUkeS72o8kX5vWRQvfW3fuocGyp+b+lX9A==
(1 row)
  • gs_decrypt(decryptstr, keystr,cryptotype, cryptomode, hashmethod)
    采纳 cryptotype 和 cryptomode 组成的加密算法以及 hashmethod 指定的 HMAC 算法,以 keystr 为密钥对 decryptstr 字符串进行解密,返回解密后的字符串。解密应用的 keystr 必须保障与加密时应用的 keystr 统一能力失常解密。

testdb=# SELECT gs_decrypt(‘AAAAAAAAAADlzZYiNQK1uB+p1gza4Lu3Moj3HdP4E1uJmqfDYBaXDLMt7RZoE0YVx9h2dMRYBQ5fhFNqqM49sUkeS72o8kX5vWRQvfW3fuocGyp+b+lX9A==’, ‘1234’, ‘aes128’, ‘cbc’, ‘sha256’);

  gs_decrypt  
--------------
 GaussDB(DWS)
(1 row)

成果剖析

有个 student 表,有 id,name 和 score 三个属性。name 能够应用哈希函数加密保留,score 能够应用对称明码算法保留。

testdb=# create table student (id int, name text, score text);
CREATE TABLE
testdb=# insert into student values (1, gs_hash('alice', 'sha256'), gs_encrypt('95', '12345', 'aes128', 'cbc', 'sha256'));
INSERT 0 1
testdb=# insert into student values (2, gs_hash('bob', 'sha256'), gs_encrypt('92', '12345', 'aes128', 'cbc', 'sha256'));
INSERT 0 1
testdb=# insert into student values (3, gs_hash('peter', 'sha256'), gs_encrypt('98', '12345', 'aes128', 'cbc', 'sha256'));
INSERT 0 1

没有密钥的用户即便领有了 select 权限也无奈看到 name 和 score 这两列加密数据。

testdb=# select * from student;
 id |                               name                               |                                                          score                                                           
----+------------------------------------------------------------------+--------------------------------------------------------------------------------------------------------------------------
  1 | 2bd806c97f0e00af1a1fc3328fa763a9269723c8db8fac4f93af71db186d6e90 | AAAAAAAAAAB26RmKZdGciLdOM1Z0sjsHg6Qh1b8taF3cY5KDVm+faJK5AT9tjufkr3Wogj3tIpFfiIEb6+miGqPHWcmKnFsArAMoBG9pPDawGs1Qze7xGg==
  2 | 81b637d8fcd2c6da6359e6963113a1170de795e4b725b84d1e0b4cfd9ec58ce9 | AAAAAAAAAAB26RmKZdGciLdOM1Z0sjsHZOHH7URkyme6r8Hfh1k0UsVbgbREjFMkgB52w+7GtUGqGgUik07ghajSD9PMIDLd/49wBCVROm2/HSOw6jzbxA==
  3 | 026ad9b14a7453b7488daa0c6acbc258b1506f52c441c7c465474c1a564394ff | AAAAAAAAAAB26RmKZdGciLdOM1Z0sjsHwv6p/OAfDUyVULAqpaHIrYJYMcqLmQSj3K/REyavfMoKB7hgUpEPXfHRutWur37bru68jjt5XcBHFBjZeMgowA==
(3 rows)

领有密钥的用户能够通过解密查看到加密数据。


testdb=# select id, gs_decrypt(score, '12345', 'aes128', 'cbc', 'sha256') from student;
 id | gs_decrypt 
----+------------
  1 | 95
  2 | 92
  3 | 98
(3 rows)

总结

数据加密是避免未受权拜访和防护数据泄露的无效技术。介绍了明码算法的基本原理和 GaussDB(DWS)数仓的加密函数,包含哈希函数 gs_hash,对称明码算法 gs_encrypt/gs_decrypt。举例说明了加密函数的应用场景。

想理解 GuassDB(DWS)更多信息,欢送微信搜寻“GaussDB DWS”关注微信公众号,和您分享最新最全的 PB 级数仓黑科技~

点击关注,第一工夫理解华为云陈腐技术~

退出移动版