你應該知道的數倉安全

摘要:防止數據泄露能夠有兩種技術路徑。一是權限管理,採用最小化受權原則對使用數據的用戶和應用程序受權。另外一種是數據加密,包括使用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用於未來建立的對象的權限的授予或回收。
image.png數據庫

語法介紹

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

其中abbreviated_grant_or_revoke子句用於指定對哪些對象進行受權或回收權限。對錶受權語法是:segmentfault

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

被授予或者取消權限角色的名稱。加密

取值範圍:已存在的角色名稱。spa

詳見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明文保存在集羣內存中,密文保存在服務管理面中。
    image.png

密鑰輪轉

出於安全考慮,用戶能夠執行密鑰輪轉操做。密鑰輪轉只輪轉集羣密鑰,不論轉數據庫祕鑰。

透明加密的後續演進

集羣級透明加密的優勢是全部數據包括用戶表和系統表都加密,適用於全部加密需求。一枚硬幣的兩面性告訴咱們,優勢也多是缺點。對全部數據庫對象加密會對數據導入和查詢帶來性能上的開銷。

爲解決此問題,後續考慮支持細粒度透明加密。好比能夠支持表級透明加密,用戶在建立表時指定屬性爲加密表,該用戶表的數據會加密存儲。用戶能夠在包含敏感數據的表中開啓加密屬性,在查詢和使用過程當中不感知加解密過程。因爲加密粒度較小,對性能的影響也較小。

透明加密是保障用戶核心數據安全的有效手段。從使用場景和原理介紹了GaussDB(DWS)數倉的透明加密特性,指出了後續透明加密特性的研究方向。

SQL函數加密

技術背景

密碼學中密碼算法能夠分爲三類:哈希函數、對稱密碼算法和非對稱密碼算法。

  • 哈希函數

哈希函數又稱爲摘要算法,對於數據data,Hash函數會生成固定長度的數據,即Hash(data)=result。這個過程是不可逆的,即Hash函數不存在反函數,沒法由result獲得data。在不該保存明文場景,好比口令(password)屬於敏感信息,系統管理員用戶也不該該知道用戶的明文口令,就應該使用哈希算法,存儲口令的單向哈希值。

實際使用中會加入鹽值和迭代次數,避免相同口令生成相同的哈希值,以防止彩虹表攻擊。
image.png

  • 對稱密碼算法

對稱密碼算法使用相同的密鑰來加密和解密數據。對稱密碼算法分爲分組密碼算法和流密碼算法。

分組密碼算法將明文分紅固定長度的分組,用密鑰對每一個分組加密。因爲分組長度固定,當明文長度不是分組長度的整數倍時,會對明文作填充處理。因爲填充的存在,分組密碼算法獲得的密文長度會大於明文長度。

流密碼算法將明文逐比特與密鑰流運算。流密碼算法不須要填充,獲得的密文長度等於明文長度。
image.png

  • 非對稱密碼算法

非對稱密碼算法,又稱爲公鑰密碼算法。算法使用兩個密鑰:公鑰和私鑰。公鑰向全部人公開,私鑰保密。非對稱密碼算法應用於密鑰協商、數字簽名、數字證書等領域。
image.png

技術實現

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級數倉黑科技~

點擊關注,第一時間瞭解華爲雲新鮮技術~

相關文章
相關標籤/搜索