摘要:避免数据泄露能够有两种技术门路。一是权限治理,采纳最小化受权准则对应用数据的用户和应用程序受权。另一种是数据加密,包含应用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 TABLEtestdb=# insert into student values (1, gs_hash('alice', 'sha256'), gs_encrypt('95', '12345', 'aes128', 'cbc', 'sha256'));INSERT 0 1testdb=# insert into student values (2, gs_hash('bob', 'sha256'), gs_encrypt('92', '12345', 'aes128', 'cbc', 'sha256'));INSERT 0 1testdb=# 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级数仓黑科技~

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