使用全密態資料庫執行個體時,不同使用者之間天然存在密文資料隔離。本文介紹如何通過授權管理實現不同使用者之間的資料融合計算,以及允許資料庫管理員(DBA)進行高危資料操作。
功能介紹
全密態資料庫中,使用者資料使用各自的資料密鑰進行加密,不同使用者之間的密文資料天然存在隔離。若需要使用多方使用者的資料進行聯集查詢,則需要由資料所有者對查詢方進行授權,以允許其訪問該資料所有者的密文資料。該過程稱為多使用者授權管理。
在全密態資料庫中,通過行為控制列表(BCL,Behavior Control List)實現多使用者授權訪問功能。通過BCL授權管理,查詢方(Subject)能夠在未瞭解授權方(Issuer,即資料所有者)資料內容的情況下完成資料聯集查詢。授權方無需擔心己方資料的泄露,同時可以通過靈活地簽發BCL授權(同意授權/撤銷授權)來限制查詢方的行為,從而及時有效地避免資料被非預期使用。
特別地,當使用者需要資料庫管理員(DBA)在全密態資料庫中執行高風險操作(如建立使用者密鑰或進行明密文轉換)時,可以通過簽發BCL授權,授權資料庫管理員(DBA)在使用者帳號下進行相關操作。在這種情況下,查詢方和授權方為同一資料庫使用者。
前提條件
已開通全密態資料庫。具體操作,請參見開通全密態資料庫。
說明RDS PostgreSQL執行個體的核心小版本大於等於20230830,如需升級核心小版本,請參見升級核心小版本。
已分別為授權方和查詢方建立帳號。具體操作,請參見建立帳號。
已定義敏感性資料。具體操作,請參見定義敏感性資料。
已使用EncDB SDK的方式,在授權方和查詢方各自完成了一次資料庫連接,並分別為二者構建了相應的測試資料。具體操作,請參見EncDB SDK用戶端使用說明。
步驟一:初始化公開金鑰和私密金鑰
分別擷取授權方和查詢方的公開金鑰與私密金鑰。
安裝OpenSSL工具。
本文以OpenSSL開源密碼工具擷取公私密金鑰為例。如果您使用Linux系統,系統會內建OpenSSL工具,無需安裝。如果您使用Windows系統,請擷取OpenSSL軟體包並安裝。
說明如果RDS PostgreSQL執行個體規格為全密態基礎版(非Intel SGX安全增強型規格的RDS PostgreSQL執行個體),需要產生基於SM2演算法的公開金鑰和私密金鑰,請執行
openssl ecparam -list_curves
命令,確認當前OpenSSL版本是否支援SM2密碼編譯演算法。如果返回結果中包含SM2,則表示支援。否則需要升級OpenSSL到支援SM2的版本(1.1.1及以上版本)。根據全密態資料庫規格,擷取授權方和查詢方的公開金鑰與私密金鑰。
產生的公開金鑰和私密金鑰檔案分別為
pub_key.pem
和pri_key_pkcs8.pem
。全密態硬體加固版(Intel SGX)
全密態硬體加固版(Intel SGX),是指Intel SGX 安全增強型規格的RDS PostgreSQL執行個體。詳細的規格清單請參見RDS PostgreSQL主執行個體規格列表。
擷取公開金鑰與私密金鑰的方法:
使用OpenSSL產生RSA私密金鑰
openssl genpkey -algorithm RSA -out pri_key_pkcs8.pem -pkeyopt rsa_keygen_bits:3072
說明3072:密鑰長度。可根據實際情況調整為其他符合安全標準的密鑰長度。
使用OpenSSL產生RSA公開金鑰
openssl rsa -in pri_key_pkcs8.pem -pubout -out pub_key.pem
全密態基礎版
全密態基礎版,是指非Intel SGX安全增強型規格的RDS PostgreSQL執行個體。詳細的規格清單請參見RDS PostgreSQL主執行個體規格列表。
擷取公開金鑰與私密金鑰的方法:
使用OpenSSL產生SM2私密金鑰
# 產生PKCS#1私密金鑰 openssl ecparam -out ec_param.pem -name SM2 -param_enc explicit -genkey # 轉換成PKCS#8私密金鑰 openssl pkcs8 -topk8 -inform PEM -in ec_param.pem -outform pem -nocrypt -out pri_key_pkcs8.pem
使用OpenSSL產生SM2公開金鑰
openssl ec -in ec_param.pem -pubout -out pub_key.pem
分別初始化授權方和查詢方的公開金鑰和私密金鑰。
分別在授權方和查詢方各自的業務代碼中,初始化授權方和查詢方的公開金鑰及私密金鑰。
說明使用OpenSSL產生的PEM檔案在內容上會自動添加分行符號(newline)。在某些編輯器中,可能會對其顯示進行最佳化,從而導致在手動拷貝時出現漏掉分行符號的情況。建議通過程式碼讀取檔案內容,以確保其準確性。
//參與方使用者私密金鑰 String userPrkPemString = readPemFile("path/to/pri_key_pkcs8.pem"); //參與方使用者公開金鑰 String userPukPemString = readPemFile("path/to/pub_key.pem"); //初始化,只需要初始化執行一次,無需重複執行 KeyManager km = sdk.getKeyManager(); km.registerCertificate(userPrkPemString, userPukPemString);
步驟二:授權多使用者訪問
定義授權內容。
String bclBodyJsonString = """{ "version": 1, "serial_num": "a121bac0-5cb3-4463-a2b2-1155ff29f4c8", "issuer_pukid": "p81x+WqYb7BR0yP0LK0qiEaxgLDqwuIjfJhgC0mMJcE=", "subject_pukid": "qIPPfgTJEEG/9WkjP0E5LLAijZ14h/Qgb2EfmBZCWSo=", "validity": { "not_after": "20250820111111+0800", "not_before": "20240820111111+0800" }, "policies": { "issuer_dek_group": [ { "min": 1, "max": 100000, "groupid": "5bc60759-5b05-45ec-afc1-ffca1229e554" } ], "result_dek": "SUBJECT", "subject_dek_group": [ { "min": 1, "max": 100000, "groupid": "53413af9-f90a-48a9-93b6-49847861b823" } ], "operation": [ "*" ], "postproc": "NULL", "preproc": "NULL" } } """;
參數說明
參數
取值範例
說明
version
1
版本號碼,當前固定為1。
serial_num
"a121bac0-5cb3-4463-a2b2-1155ff29f4c8"
序號,UUID格式,自訂,全域唯一。
說明可使用UUID產生工具產生序號。
issuer_pukid
"p81x+WqYb7BR0yP0LK0qiEaxgLDqwuIjfJhgC0mMJcE="
授權方公開金鑰摘要。基於產生的公開金鑰檔案(pub_key.pem),擷取方法:
全密態硬體加固版(Intel SGX)
openssl sha256 -binary pub_key.pem | openssl base64
全密態基礎版
openssl sm3 -binary pub_key.pem | openssl base64
subject_pukid
"qIPPfgTJEEG/9WkjP0E5LLAijZ14h/Qgb2EfmBZCWSo="
查詢方使用者公開金鑰摘要,配置方法與issuer_pukid相同。
validity
{ "not_before": "20240820111111+0800", "not_after": "20250820111111+0800"}
授權有效期間。需使用GeneralizedTime時間格式。
"not_before":有效期間開始時間。
"not_after":有效期間結束時間。
policies
issuer_dek_group
[ { "min": 1, "max": 100000, "groupid": "5bc60759-5b05-45ec-afc1-ffca1229e554" }]
授權方允許使用的資料密鑰(DEK)分組。
"groupid":DEK分組ID。
"min":分組內授權的最小DEK ID。
"max":分組內授權的最大DEK ID。
說明給定groupid下,DEK ID取值嚴格單調遞增。
groupid擷取方法:
SELECT encdb_get_cc_entry_by_name(encdb.keyname_generate('<user_name>', '<database_name>', '<schema_name>', '<table_name>', '<column_name>'));
說明<user_name>
為授權方的使用者名稱。<table_name>
為授權訪問的授權方目標表名稱。<column_name>
為授權訪問的授權方目標列名稱。
subject_dek_group
[ { "min": 1, "max": 100000, "groupid": "53413af9-f90a-48a9-93b6-49847861b823" }]
查詢方允許使用的資料密鑰(DEK)分組。
"groupid":DEK分組ID。
"min":分組內授權的最小DEK ID。
"max":分組內授權的最大DEK ID。
說明給定groupid下,DEK ID取值嚴格單調遞增。
擷取groupid方法:
SELECT encdb_get_cc_entry_by_name(encdb.keyname_generate('<user_name>', '<database_name>', '<schema_name>', '<table_name>', '<column_name>'));
說明<user_name>
為查詢方的使用者名稱。<table_name>
為授權訪問的查詢方目標表名稱。<column_name>
為授權訪問的查詢方目標列名稱。
result_dek
"SUBJECT"
計算結果使用的DEK加密方式。
"SUBJECT":使用當前計算中查詢方的DEK加密。
"ISSUER":使用當前計算中授權方的DEK加密。
DEK ID:使用指定DEK ID的DEK加密。
重要如果使用
DEK ID
,直接在此參數配置DEK ID的內容,無需添加雙引號。
operation
[ "*"]
允許的計算操作。
"encrypt":加密。
"decrypt":解密。
"cmp":比較。
"*":授權所有操作。
postproc
"NULL"
計算前需要的前置預先處理操作。當前固定為NULL,表示無前置預先處理操作。
preproc
"NULL"
計算後需要的後置預先處理操作。當前固定為NULL,表示無後置預先處理操作。
授權多使用者訪問。
授權方使用己方公開金鑰和私密金鑰,簽發BCL,授權查詢方訪問目標列的資料。
boolean isIssuer = true; bclBodyJsonString = km.issueBCL(bclBodyJsonString, userPukPemString, userPrkPemString, isIssuer);
查詢方使用己方公開金鑰和私密金鑰,簽發BCL,訪問已授權的資料。
boolean isIssuer = false; bclBodyJsonString = km.issueBCL(bclBodyJsonString, userPukPemString, userPrkPemString, isIssuer);
步驟三:(可選)撤銷授權
如果授權方需要撤銷授權,則使用如下配置。
定義撤銷授權內容。
String brlBodyJsonString = """{ "version": 1, "pukid": "dYJ3Wfj/n0eZbuqgQjv8bnBdPXGyWGOlxE/uMy16NXo=", "this_update": "20220819111128+0800", "next_update": "20220919111128+0800", "revoked": [ { "revocation_date": "20220819111128+0800", "serial_num": "a121bac0-5cb3-4463-a2b2-1155ff29f4c8" } ] } """;
參數說明
參數
取值範例
說明
version
1
版本號碼,當前固定為1。
pukid
"dYJ3Wfj/n0eZbuqgQjv8bnBdPXGyWGOlxE/uMy16NXo="
授權方公開金鑰摘要。需配置為請求授權時BCL中的授權方公開金鑰摘要。配置方法與定義授權內容中相同。
this_update
"20220819111128+0800"
本次撤銷列表更新時間,需使用GeneralizedTime時間格式。
next_update
"20220919111128+0800"
下次撤銷列表更新時間,需使用GeneralizedTime時間格式。
revoked
revocation_date
"20220819111128+0800"
撤銷時間,需使用GeneralizedTime時間格式。
serial_num
"a121bac0-5cb3-4463-a2b2-1155ff29f4c8"
序號,UUID格式,需配置為請求授權時BCL中的序號。
授權方簽發BCL撤銷授權。
brlBodyJsonString = km.revokeBCL(brlBodyJsonString, userPukPemString, userPrkPemString);
應用情境樣本
樣本一:授權高危操作-明文和密文轉換
在存量明文資料庫需要啟用全密態資料庫功能,而又不希望進行資料移轉的情況下,可以通過在原資料庫上執行明密文類型的轉換,來高效地切換至密文模式(詳情請參見明文和密文的轉換)。出於安全性考慮,全密態資料庫預設不允許資料庫使用者(包括資料庫管理員)直接在全密態資料庫上對明密文進行原地轉換,這類操作被視為資料安全高危操作。
在明確資料安全風險的前提下,使用者可通過簽發自授權的BCL,授權使用者帳號進行明密文類型的原地轉換。在此過程中,查詢方和授權方均為同一使用者帳號,即:
定義授權內容時,BCL授權中的
issuer_pukid
與subject_pukid
相同、issuer_dek_group
與subject_dek_group
相同。初始化公開金鑰和私密金鑰時,授權方和查詢方使用同一對公開金鑰和私密金鑰,即授權方的
userPukPemString
和userPrkPemString
與查詢方的對應密鑰相同。
完成自授權BCL簽發後,即可在被授權帳號下執行相應操作。完整範例程式碼如下。
樣本二:多方資料聯集查詢
以資料平台公司的業務情境為例,該平台通過合法渠道,在獲得使用者授權後,收集使用者資訊,並產生使用者畫像表。經授權後,平台能夠將資料提供給第三方(例如保險公司),以便進行多方資料融合計算,從而實現聯合營銷。詳情請參見多方資料融合計算。
以下為多方資料聯集查詢的完整範例程式碼。