云服务器内容精选

  • 行级访问控制设置 行级访问控制的目的是控制表中行级数据可见性,通过在数据表上预定义Filter,在查询优化阶段将满足条件的表达式应用到执行计划上,影响最终的执行结果。当前受影响的SQL语句包括SELECT,UPDATE,DELETE。 用户可以使用CREATE ROW LEVEL SECURITY POLICY语句在表上创建行访问控制策略(Row Level Security)。 该策略针对特定数据库用户、特定SQL操作生效的表达式。当数据库用户对数据表访问时,若SQL满足数据表特定的Row Level Security策略,在查询优化阶段将满足条件的表达式,按照属性(PERMISSIVE | RESTRICTIVE)类型,通过AND或OR方式拼接,应用到执行计划上。 对表创建了行级访问控制策略后,只有打开该表的行访问控制开关(ALTER TABLE ... ENABLE ROW LEVEL SECURITY),策略才能生效。
  • 示例 以员工表emp,表的属主alice及角色matu、july为例,简要介绍数据脱敏过程。其中,表emp包含员工的姓名、手机号、邮箱、银行卡号、薪资等隐私数据 使用管理员用户连接数据库后,创建角色alice、matu和july。 1 2 3 CREATE ROLE alice PASSWORD 'password'; CREATE ROLE matu PASSWORD 'password'; CREATE ROLE july PASSWORD 'password'; 赋予alice、matu和july当前数据库的模式权限。 1 GRANT ALL PRIVILEGES on schema public to alice,matu,july; 切换至角色alice,创建表emp并插入三条员工信息。 1 2 3 4 5 6 7 SET ROLE alice PASSWORD 'password'; CREATE TABLE emp(id int, name varchar(20), phone_no varchar(11), card_no number, card_string varchar(19), email text, salary numeric(100, 4), birthday date); INSERT INTO emp VALUES(1, 'anny', '13420002340', 1234123412341234, '1234-1234-1234-1234', 'smithWu@163.com', 10000.00, '1999-10-02'); INSERT INTO emp VALUES(2, 'bob', '18299023211', 3456345634563456, '3456-3456-3456-3456', '66allen_mm@qq.com', 9999.99, '1989-12-12'); INSERT INTO emp VALUES(3, 'cici', '15512231233', NULL, NULL, 'jonesishere@sina.com', NULL, '1992-11-06'); alice将表emp的读取权限授予matu、july。 1 GRANT SELECT ON emp TO matu, july; 创建脱敏策略mask_emp,仅alice可查看员工所有信息,matu和july对员工银行卡号和薪资数据不可见。字段card_no是数值类型,采用MASK_FULL全脱敏成固定值0;字段card_string是字符类型,采用MASK_PARTIAL按指定的输入输出格式对原始数据进行部分脱敏;字段salary是数值类型,采用MASK_PARTIAL指定数字9部分脱敏倒数第二位前的所有数位值。 1 2 3 4 CREATE REDACTION POLICY mask_emp ON emp WHEN (current_user IN ('matu', 'july')) ADD COLUMN card_no WITH mask_full(card_no), ADD COLUMN card_string WITH mask_partial(card_string, 'VVVVFVVVVFVVVVFVVVV','VVVV-VVVV-VVVV-VVVV','#',1,12), ADD COLUMN salary WITH mask_partial(salary, '9', 1, length(salary) - 2); 切换到matu和july,查看员工表emp。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SET ROLE matu PASSWORD 'password'; SELECT * FROM emp; id | name | phone_no | card_no | card_string | email | salary | birthday ----+------+-------------+---------+---------------------+----------------------+------------+--------------------- 1 | anny | 13420002340 | 0 | ####-####-####-1234 | smithWu@163.com | 99999.9990 | 1999-10-02 00:00:00 2 | bob | 18299023211 | 0 | ####-####-####-3456 | 66allen_mm@qq.com | 9999.9990 | 1989-12-12 00:00:00 3 | cici | 15512231233 | | | jonesishere@sina.com | | 1992-11-06 00:00:00 (3 rows) SET ROLE july PASSWORD 'password'; SELECT * FROM emp; id | name | phone_no | card_no | card_string | email | salary | birthday ----+------+-------------+---------+---------------------+----------------------+------------+--------------------- 1 | anny | 13420002340 | 0 | ####-####-####-1234 | smithWu@163.com | 99999.9990 | 1999-10-02 00:00:00 2 | bob | 18299023211 | 0 | ####-####-####-3456 | 66allen_mm@qq.com | 9999.9990 | 1989-12-12 00:00:00 3 | cici | 15512231233 | | | jonesishere@sina.com | | 1992-11-06 00:00:00 (3 rows) 若需要matu也有员工所有信息的查看权限,只有july不可见,修改策略生效范围即可。 1 2 SET ROLE alice PASSWORD 'password'; ALTER REDACTION POLICY mask_emp ON emp WHEN(current_user = 'july'); 切换到matu和july,重新查看员工表emp。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 SET ROLE matu PASSWORD 'password'; SELECT * FROM emp; id | name | phone_no | card_no | card_string | email | salary | birthday ----+------+-------------+------------------+---------------------+----------------------+------------+--------------------- 1 | anny | 13420002340 | 1234123412341234 | 1234-1234-1234-1234 | smithWu@163.com | 10000.0000 | 1999-10-02 00:00:00 2 | bob | 18299023211 | 3456345634563456 | 3456-3456-3456-3456 | 66allen_mm@qq.com | 9999.9900 | 1989-12-12 00:00:00 3 | cici | 15512231233 | | | jonesishere@sina.com | | 1992-11-06 00:00:00 (3 rows) SET ROLE july PASSWORD 'password'; SELECT * FROM emp; id | name | phone_no | card_no | card_string | email | salary | birthday ----+------+-------------+---------+---------------------+----------------------+------------+--------------------- 1 | anny | 13420002340 | 0 | ####-####-####-1234 | smithWu@163.com | 99999.9990 | 1999-10-02 00:00:00 2 | bob | 18299023211 | 0 | ####-####-####-3456 | 66allen_mm@qq.com | 9999.9990 | 1989-12-12 00:00:00 3 | cici | 15512231233 | | | jonesishere@sina.com | | 1992-11-06 00:00:00 (3 rows) 员工信息phone_no、email和birthday也是隐私数据,更新脱敏策略mask_emp,新增三个脱敏列。 1 2 3 4 SET ROLE alice PASSWORD 'password'; ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN phone_no WITH mask_partial(phone_no, '*', 4); ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN email WITH mask_partial(email, '*', 1, position('@' in email)); ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN birthday WITH mask_full(birthday); 切换到july,查看表emp数据。 1 2 3 4 5 6 7 8 SET ROLE july PASSWORD 'password'; SELECT * FROM emp; id | name | phone_no | card_no | card_string | email | salary | birthday ----+------+-------------+---------+---------------------+----------------------+------------+--------------------- 1 | anny | 134******** | 0 | ####-####-####-1234 | ********163.com | 99999.9990 | 1970-01-01 00:00:00 2 | bob | 182******** | 0 | ####-####-####-3456 | ***********qq.com | 9999.9990 | 1970-01-01 00:00:00 3 | cici | 155******** | | | ************sina.com | | 1970-01-01 00:00:00 (3 rows) 通过视图redaction_policies和redaction_columns查看当前脱敏策略mask_emp的详细信息。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 SELECT * FROM redaction_policies; object_schema | object_owner | object_name | policy_name | expression | enable | policy_description | inherited ---------------+--------------+-------------+-------------+-----------------------------------+--------+--------------------+----------- public | alice | emp | mask_emp | ("current_user"() = 'july'::name) | t | | f (1 row) SELECT object_name, column_name, function_info FROM redaction_columns; object_name | column_name | function_info -------------+-------------+------------------------------------------------------------------------------------------------------- emp | card_no | mask_full(card_no) emp | card_string | mask_partial(card_string, 'VVVVFVVVVFVVVVFVVVV'::text, 'VVVV-VVVV-VVVV-VVVV'::text, '#'::text, 1, 12) emp | email | mask_partial(email, '*'::text, 1, "position"(email, '@'::text)) emp | salary | mask_partial(salary, '9'::text, 1, (length((salary)::text) - 2)) emp | birthday | mask_full(birthday) emp | phone_no | mask_partial(phone_no, '*'::text, 4) (6 rows) 新增一列salary_info,若需要将文本类型的薪资信息统一脱敏成“*.*”,可以创建自定义脱敏函数实现。此处采用PL/PGSQL语言定义脱敏函数mask_regexp_salary,创建脱敏列时,只需自定义脱敏的函数名和参数列表,详细内容可参考 GaussDB (DWS)用户自定义函数。 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 SET ROLE alice PASSWORD 'password'; ALTER TABLE emp ADD COLUMN salary_info TEXT; UPDATE emp SET salary_info = salary::text; CREATE FUNCTION mask_regexp_salary(salary_info text) RETURNS text AS $$ SELECT regexp_replace($1, '[0-9]+','*','g'); $$ LANGUAGE SQL STRICT SHIPPABLE; ALTER REDACTION POLICY mask_emp ON emp ADD COLUMN salary_info WITH mask_regexp_salary(salary_info); SET ROLE july PASSWORD 'password'; SELECT id, name, salary_info FROM emp; id | name | salary_info ----+------+------------- 1 | anny | *.* 2 | bob | *.* 3 | cici | (3 rows) 无需为表emp设置敏感策略,删除脱敏策略mask_emp。 1 2 SET ROLE alice PASSWORD 'password'; DROP REDACTION POLICY mask_emp ON emp;
  • 通用哈希函数 digest() digest()函数可以根据不同的算法生成数据的二进制哈希值,语法如下: digest(data text, type text) returns bytea digest(data bytea, type text) returns bytea 其中,data是原始数据,type是加密算法包括md5、sha1、sha224、sha256、sha384、sha512和sm3;函数的返回结果为二进制字符串。 示例: 使用digest() 函数对字符串GaussDB(DWS)进行sha256加密存储: select digest('GaussDB(DWS)', 'sha256'); digest -------------------------------------------------------------------- \xcc2d1b97c6adfba44bbce7386516f63f16fc6e6a10bd938861d3aba501ac8aab (1 row)
  • 密码哈希函数 crypt()和gen_salt()函数专用于哈希密码。crypt()执行哈希用于加密数据,gen_salt()用于生成加盐哈希。 crypt()中的算法和普通的MD5或者SHA1哈希算法存在以下不同之处: crypt()中算法很慢。由于密码包含的数据量很小,这是增加暴力破解难度的唯一方法。 它们使用一个随机值(称为salt,即盐值),因此这样具有相同口令的用户将得到不同的密文口令。这也是针对破解算法提供一种额外的安全保护。 它们的结果中包括了算法类型,因此可以针对不同用户使用不同的算法对密码进行加密。 其中一些算法具有自适应性,意味着当计算机性能变得更快时,可以调整该算法使其变得更慢,而不会产生与已有密码的不兼容性。 crypt()函数所支持的算法如下表: 表1 crypt()支持的算法 算法 密码最大长度 自适应性 Salt位数 输出结果长度 描述 bf 72 √ 128 60 基于Blowfish的2a变种算法 md5 unlimited × 48 34 基于MD5的加密算法 xdes 8 √ 24 20 扩展DES des 8 × 12 13 原生UNIX加密算法
  • 随机数据函数 gen_random_bytes()函数用于生成具有强加密性的随机字节。 gen_random_bytes(count integer) returns bytea 其中,count表示返回的字节数,取值为1到1024。 示例: SELECT gen_random_bytes(16); gen_random_bytes ------------------------------------ \x1f1eddc11153afdde0f9e1229f8f4caf (1 row) gen_random_uuid()函数用于返回一个version 4的随机UUID。 SELECT gen_random_uuid(); gen_random_uuid -------------------------------------- 2bd664a2-b760-4859-8af6-8d09ccc5b830
  • 原始加密函数 原始加密函数仅仅会对数据运行一次加密,不支持PGP加密的任何高级功能,因此存在以下问题: 直接将用户密钥作为加密密钥。 不提供任何完整性检查来校验加密后的数据是否被修改。 需要用户自己关联所有加密参数,包括初始值(IV)。 不支持处理文本数据。 因此,在引入了PGP加密后,不建议使用这些原始加密函数。 encrypt(data bytea, key bytea, type text) returns bytea decrypt(data bytea, key bytea, type text) returns bytea encrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea 其中,data是需要加密的数据;type用于指定加密/解密方法。type参数的语法如下: algorithm [ - mode ] [ /pad: padding ]
  • 行级访问控制设置 行级访问控制的目的是控制表中行级数据可见性,通过在数据表上预定义Filter,在查询优化阶段将满足条件的表达式应用到执行计划上,影响最终的执行结果。当前受影响的SQL语句包括SELECT,UPDATE,DELETE。 用户可以使用CREATE ROW LEVEL SECURITY POLICY语句在表上创建行访问控制策略(Row Level Security)。 该策略针对特定数据库用户、特定SQL操作生效的表达式。当数据库用户对数据表访问时,若SQL满足数据表特定的Row Level Security策略,在查询优化阶段将满足条件的表达式,按照属性(PERMISSIVE | RESTRICTIVE)类型,通过AND或OR方式拼接,应用到执行计划上。 对表创建了行级访问控制策略后,只有打开该表的行访问控制开关(ALTER TABLE ... ENABLE ROW LEVEL SECURITY),策略才能生效。
  • 通用哈希函数 digest() digest()函数可以根据不同的算法生成数据的二进制哈希值,语法如下: digest(data text, type text) returns bytea digest(data bytea, type text) returns bytea 其中,data是原始数据,type是加密算法包括md5、sha1、sha224、sha256、sha384、sha512和sm3;函数的返回结果为二进制字符串。 示例: 使用digest() 函数对字符串GaussDB(DWS)进行sha256加密存储: select digest('GaussDB(DWS)', 'sha256'); digest -------------------------------------------------------------------- \xcc2d1b97c6adfba44bbce7386516f63f16fc6e6a10bd938861d3aba501ac8aab (1 row)
  • 随机数据函数 gen_random_bytes()函数用于生成具有强加密性的随机字节。 gen_random_bytes(count integer) returns bytea 其中,count表示返回的字节数,取值为1到1024。 示例: SELECT gen_random_bytes(16); gen_random_bytes ------------------------------------ \x1f1eddc11153afdde0f9e1229f8f4caf (1 row) gen_random_uuid()函数用于返回一个version 4的随机UUID。 SELECT gen_random_uuid(); gen_random_uuid -------------------------------------- 2bd664a2-b760-4859-8af6-8d09ccc5b830
  • 原始加密函数 原始加密函数仅仅会对数据运行一次加密,不支持PGP加密的任何高级功能,因此存在以下问题: 直接将用户密钥作为加密密钥。 不提供任何完整性检查来校验加密后的数据是否被修改。 需要用户自己关联所有加密参数,包括初始值(IV)。 不支持处理文本数据。 因此,在引入了PGP加密后,不建议使用这些原始加密函数。 encrypt(data bytea, key bytea, type text) returns bytea decrypt(data bytea, key bytea, type text) returns bytea encrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea decrypt_iv(data bytea, key bytea, iv bytea, type text) returns bytea 其中,data是需要加密的数据;type用于指定加密/解密方法。type参数的语法如下: algorithm [ - mode ] [ /pad: padding ]
  • 密码哈希函数 crypt()和gen_salt()函数专用于哈希密码。crypt()执行哈希用于加密数据,gen_salt()用于生成加盐哈希。 crypt()中的算法和普通的MD5或者SHA1哈希算法存在以下不同之处: crypt()中算法很慢。由于密码包含的数据量很小,这是增加暴力破解难度的唯一方法。 它们使用一个随机值(称为salt,即盐值),因此这样具有相同口令的用户将得到不同的密文口令。这也是针对破解算法提供一种额外的安全保护。 它们的结果中包括了算法类型,因此可以针对不同用户使用不同的算法对密码进行加密。 其中一些算法具有自适应性,意味着当计算机性能变得更快时,可以调整该算法使其变得更慢,而不会产生与已有密码的不兼容性。 crypt()函数所支持的算法如下表: 表1 crypt()支持的算法 算法 密码最大长度 自适应性 Salt位数 输出结果长度 描述 bf 72 √ 128 60 基于Blowfish的2a变种算法 md5 unlimited × 48 34 基于MD5的加密算法 xdes 8 √ 24 20 扩展DES des 8 × 12 13 原生UNIX加密算法
  • 使用函数加解密 GaussDB(DWS)支持使用以下函数对字符串进行加解密。 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。支持的加密数据类型:目前数据库支持的数值类型,字符类型,二进制类型中的RAW,日期/时间类型中的DATE、TIMESTAMP、SMALLDATETIME。keystr的长度范围与加密算法相关,为1~KeyLen字节。当cryptotype为aes128和sm4时,KeyLen为16,aes192时KeyLen为24,aes256时KeyLen为32。 返回值类型:text 返回值长度:至少为 4*[(maclen + 56)/3] 字节,不超过 4*[(Len + maclen + 56)/3] 字节,其中Len为加密前数据长度(单位为字节),maclen为HMAC值的长度,当hashmethod为sha256和sm3时maclen为32,sha384时maclen为48,sha512时maclen为64。即当hashmethod为sha256和sm3时,返回值长度至少为120字节,不超过4*[(Len + 88)/3] 字节;当hashmethod为sha384时,返回值长度至少为140字节,不超过4*[(Len + 104)/3] 字节;当hashmethod为sha512时,返回值长度至少为160字节,不超过4*[(Len + 120)/3] 字节; 示例: 12345 SELECT gs_encrypt('GaussDB(DWS)', '1234', 'aes128', 'cbc', 'sha256'); gs_encrypt -------------------------------------------------------------------------------------------------------------------------- AAAAAAAAAACcFjDc CS bop7D87sOa2nxTFrkE9RJQGK34ypgrOPsFJIqggI8tl+eMDcQYT3po98wPCC7VBfhv7mdBy7IVnzdrp0rdMrD6/zTl8w0v9/s2OA==(1 row) 该函数8.1.1及以上集群版本支持。 由于该函数的执行过程需要传入解密口令,为了安全起见,gsql工具不会将该函数记录入执行历史。即无法在gsql里通过上下翻页功能找到该函数的执行历史。 在同一张数据表中,加密函数ge_encrypt与gs_encrypt_aes128不要混合使用。 gs_decrypt(decryptstr, keystr,cryptotype, cryptomode, hashmethod) 描述:采用cryptotype和cryptomode组成的加密算法以及hashmethod指定的HMAC算法,以keystr为密钥对decryptstr字符串进行解密,返回解密后的字符串。解密使用的keystr必须保证与加密时使用的keystr一致才能正常解密。keystr不得为空。 返回值类型:text 示例: 12345 SELECT gs_decrypt('AAAAAAAAAACcFjDcCSbop7D87sOa2nxTFrkE9RJQGK34ypgrOPsFJIqggI8tl+eMDcQYT3po98wPCC7VBfhv7mdBy7IVnzdrp0rdMrD6/zTl8w0v9/s2OA==', '1234', 'aes128', 'cbc', 'sha256'); gs_decrypt -------------- GaussDB(DWS)(1 row) 该函数8.1.1及以上集群版本支持。 由于该函数的执行过程需要传入解密口令,为了安全起见,gsql工具不会将该函数记录入执行历史。即无法在gsql里通过上下翻页功能找到该函数的执行历史。 此函数需要结合gs_encrypt加密函数共同使用,且加密算法和HMAC算法要保证一致。 gs_encrypt_aes128(encryptstr,keystr) 描述:以keystr为密钥对encryptstr字符串进行加密,返回加密后的字符串。keystr的长度范围为1~16字节。支持的加密数据类型:目前数据库支持的数值类型,字符类型,二进制类型中的RAW,日期/时间类型中的DATE、TIMESTAMP、SMALLDATETIME。 返回值类型:text 返回值长度:至少为92字节,不超过 4*[(Len+68)/3] 字节,其中Len为加密前数据长度(单位为字节)。 示例: 123456 SELECT gs_encrypt_aes128('MPPDB','1234'); gs_encrypt_aes128-------------------------------------------------------------------------------------gwditQLQG8NhFw4OuoKhhQJoXojhFlYkjeG0aYdSCtLCnIUgkNwvYI04KbuhmcGZp8jWizBdR1vU9CspjuzI0lbz12A=(1 row) 由于该函数的执行过程需要传入解密口令,为了安全起见,gsql工具不会将该函数记录入执行历史。即无法在gsql里通过上下翻页功能找到该函数的执行历史。 在同一张数据表中,加密函数gs_encrypt_aes128与ge_encrypt不要混合使用。 gs_decrypt_aes128(decryptstr,keystr) 描述:以keystr为密钥对decryptstr字符串进行解密,返回解密后的字符串。解密使用的keystr必须保证与加密时使用的keystr一致才能正常解密。keystr不得为空。 返回值类型:text 示例: 12345 SELECT gs_decrypt_aes128('gwditQLQG8NhFw4OuoKhhQJoXojhFlYkjeG0aYdSCtLCnIUgkNwvYI04KbuhmcGZp8jWizBdR1vU9CspjuzI0lbz12A=','1234'); gs_decrypt_aes128 ------------------- MPPDB(1 row) 由于该函数的执行过程需要传入解密口令,为了安全起见,gsql工具不会将该函数记录入执行历史。即无法在gsql里通过上下翻页功能找到该函数的执行历史。 此函数需要结合gs_encrypt_aes128加密函数共同使用。 gs_hash(hashstr, hashmethod) 描述:以hashmethod算法对hashstr字符串进行信息摘要,返回信息摘要字符串。支持的hashmethod:sha256, sha384, sha512, sm3。该函数8.1.1及以上集群版本支持。 返回值类型:text 返回值长度:sha256和sm3返回64字节,sha384返回96字节,sha512返回128字节。 示例: 12345 SELECT gs_hash('GaussDB(DWS)', 'sha256'); gs_hash -------------------------------------------------------------------------------------------------- e59069daa6541ae20af7c747662702c731b26b8abd7a788f4d15611aa0db608efdbb5587ba90789a983f85dd51766609(1 row) md5(string) 描述:将string使用MD5加密,并以16进制数作为返回值。 MD5的安全性较低,不建议使用。 返回值类型:text 示例: 12345 SELECT md5('ABC'); md5 ---------------------------------- 902fbdd2b1df0c4f70b4a5d23525e932(1 row) 父主题: 敏感数据管理