全密態數據庫可以用于多方數據融合計算,支持數據所有者授權第三方使用數據參與計算,實現聯合營銷等多種場景。
場景介紹
以某數據平臺公司業務場景為例,該平臺通過合法渠道,經用戶授權后,收集了用戶信息,生成用戶畫像表(portrait),可以授權第三方(例如保險公司)使用數據進行多方數據融合計算,實現聯合營銷。
手機號(phone) | 年齡(age) | 是否有車(have_car) | 年消費金額(annual_consume) |
13900001111 | 29 | N | 20000 |
13900002222 | 34 | Y | 10000 |
上表中數據僅為示例。
保險公司希望借助數據平臺公司的數據,幫助保險公司發展潛在用戶,例如向有車一族定向推送車輛保險。
聯合查詢應滿足:
未授權時,聯合查詢SQL失敗,提示無權限。
簽發BCL查詢授權,聯合查詢SQL成功,并返回密文結果。
簽發BCL解密授權,授權結果方可以解密得到明文結果。
多方數據融合計算流程示例
本文以個人隱私保護中的保險公司為例進行舉例,請先參見個人隱私保護完成相關配置。
數據平臺公司
DBA創建用戶和數據庫表。
-------- 創建用戶 -------- -- 數據平臺公司 CREATE USER ly; -- 為數據平臺公司創建用戶畫像表 CREATE TABLE portrait ( phone enc_text, age enc_int4, have_car enc_text, annual_consume enc_int8 ); -- 授權數據平臺公司訪問數據表 GRANT ALL ON portrait TO ly;
注冊數據平臺公司賬號。
說明EncDB Tool工具將會基于傳入的參數自動生成SQL語句,您需要將生成的SQL在數據庫中執行。
./genEncdbSQLCommand.sh -r MEK_PROVISION --mek sample/default_mek_ly.bin -e default_enclave_public_key.pem -c ${cipher_suite} # 獲取數據平臺公司MEKID,可以通過SQL查詢獲得:SELECT encdb_get_current_mek_id(); # 本文以6953973016013340672為例 mekid_ly = 6953973016013340672 ./genEncdbSQLCommand.sh -r BCL_REGISTER --mekid ${mekid_ly} --mek sample/default_mek_ly.bin --puk sample/usr_puk_ly.pem --pri sample/usr_pri_ly.pem -c ${cipher_suite}
平臺公司為用戶畫像表創建加密密鑰。
說明如下命令需使用
ly
用戶執行。命令中的
encdb.dek_xxx()
和encdb.keyname_xxx()
為類型轉換函數,更多用法,請參見類型轉換函數說明。
-- 創建一個dek,記錄groupid,例如 fd89d386-ee00-4e0e-9e5f-66efb4c124aa SELECT encdb.dek_generate(encdb.keyname_generate('ly','demo','public','portrait','phone')); -- 此處僅為示例,同步給所有列,即共用一個dek SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ly','demo','public','portrait','age'),encdb.keyname_generate('ly','demo','public','portrait','phone')); SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ly','demo','public','portrait','have_car'),encdb.keyname_generate('ly','demo','public','portrait','phone')); SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ly','demo','public','portrait','annual_consume'),encdb.keyname_generate('ly','demo','public','portrait','phone'));
正常情況下,不允許用戶直接通過SQL加密數據(不安全),用戶需要明確授權該行為。
編輯BCL內容,將目標dek的授權范圍(包括groupid)更新到BCL中。
./setGroupIdBCL.sh -l fd89d386-ee00-4e0e-9e5f-66efb4c124aa
說明本示例中的
fd89d386-ee00-4e0e-9e5f-66efb4c124aa
僅為示例,實際取值請從如下命令中獲取:SELECT encdb.dek_generate(encdb.keyname_generate('ly','demo','public','portrait','phone'));
簽發BCL。
./genEncdbSQLCommand.sh -r BCL_ISSUE --subject_sign --spriv sample/usr_pri_ly.pem --spuk sample/usr_puk_ly.pem --ipuk sample/usr_puk_ly.pem --bcl sample/bcl_for_ly_insert.txt -c ${cipher_suite} ./genEncdbSQLCommand.sh -r BCL_ISSUE --issuer_sign --ipriv sample/usr_pri_ly.pem --spuk sample/usr_puk_ly.pem --ipuk sample/usr_puk_ly.pem --bcl sample/bcl_for_ly_insert.txt -c ${cipher_suite}
數據平臺公司寫入數據。
說明如下命令需使用
ly
用戶執行。INSERT INTO portrait VALUES(encdb.enc_text_encrypt('13900001111',encdb.keyname_generate('ly','demo','public','portrait','phone')), encdb.enc_int4_encrypt('29',encdb.keyname_generate('ly','demo','public','portrait','age')), encdb.enc_text_encrypt('N',encdb.keyname_generate('ly','demo','public','portrait','have_car')), encdb.enc_int8_encrypt('2',encdb.keyname_generate('ly','demo','public','portrait','annual_consume'))); INSERT INTO portrait VALUES(encdb.enc_text_encrypt('13900002222',encdb.keyname_generate('ly','demo','public','portrait','phone')), encdb.enc_int4_encrypt('34',encdb.keyname_generate('ly','demo','public','portrait','age')), encdb.enc_text_encrypt('Y',encdb.keyname_generate('ly','demo','public','portrait','have_car')), encdb.enc_int8_encrypt('1',encdb.keyname_generate('ly','demo','public','portrait','annual_consume')));
保險公司
保險公司銷售部門為了向有車一族推送車輛保險,發起聯合查詢:
SELECT * FROM person ps JOIN portrait pt ON ps.phone = pt.phone WHERE hava_car = 'Y';
保險公司銷售部門授權encrypt權限。
編輯BCL內容,將目標dek的授權范圍(包括groupid)更新到BCL中。
./setGroupIdBCL.sh -s 7903d109-f3e0-4f3e-b815-3682cb8bd6db
說明本示例中的
7903d109-f3e0-4f3e-b815-3682cb8bd6db
僅為示例,銷售使用默認密鑰進行加密,對應groupid可以通過如下命令查詢:# 獲取銷售部門賬號MEKID,以2715553450389700608為例 SELECT encdb_get_current_mek_id(); # 獲取groupid SELECT groupid FROM encdb.encdb_internal_dek_table WHERE mekid = 2715553450389700608;
簽發BCL。
./genEncdbSQLCommand.sh -r BCL_ISSUE --subject_sign --spriv sample/usr_pri_sale.pem --spuk sample/usr_puk_sale.pem --ipuk sample/usr_puk_sale.pem --bcl sample/bcl_for_sale_insert.txt -c ${cipher_suite} ./genEncdbSQLCommand.sh -r BCL_ISSUE --issuer_sign --ipriv sample/usr_pri_sale.pem --spuk sample/usr_puk_sale.pem --ipuk sample/usr_puk_sale.pem --bcl sample/bcl_for_sale_insert.txt -c ${cipher_suite}
保險公司銷售部門查詢數據。
銷售部門未得到數據平臺公司授權,使用數據平臺公司數據:
說明如下命令需使用
ins_sale
用戶執行。SELECT * FROM person ps JOIN portrait pt ON ps.phone = pt.phone WHERE pt.have_car = encdb.enc_text_encrypt('Y',encdb.keyname_generate('ins_sale','demo', Null, Null, Null)); WARNING: -- encdb -- -- Untrusted log -- 4 - src/core/untrusted/src/encdb_untrusted_enclave.cpp,256,encdb_ecall: Select BCL (subject_mekid: 2715553450389700608, issuer_mekid: 6953973016013340672) from table fail - returned 0xfa030000 ERROR: pg_enc_cmp_eq: encrypted type equal errno: fa030000
說明如果出現
ERROR: permission denied for table portrait
的錯誤時,執行GRANT SELECT ON portrait TO ins_sale;
授權訪問表。銷售部門獲得數據平臺公司及數據部門授權后,使用數據平臺公司數據。
銷售部門向平臺公司發起授權,平臺公司審批后,簽發授權。
# 銷售部門發起授權請求:SUBJECT申請方簽名確認 ./genEncdbSQLCommand.sh -r BCL_ISSUE --subject_sign --spriv sample/usr_pri_sale.pem --spuk sample/usr_puk_sale.pem --ipuk sample/usr_puk_ly.pem --bcl sample/bcl_ly_for_sale_select.txt -c ${cipher_suite} # 平臺公司審批后確認授權、并簽發BCL:ISSUER授權方簽名確認 ./genEncdbSQLCommand.sh -r BCL_ISSUE --issuer_sign --ipriv sample/usr_pri_ly.pem --spuk sample/usr_puk_sale.pem --ipuk sample/usr_puk_ly.pem --bcl sample/bcl_ly_for_sale_select.txt -c ${cipher_suite}
銷售部門向數據部門發起授權,數據部門審批后,簽發授權。
# 銷售部門發起授權請求:SUBJECT申請方簽名確認 ./genEncdbSQLCommand.sh -r BCL_ISSUE --subject_sign --spriv sample/usr_pri_sale.pem --spuk sample/usr_puk_sale.pem --ipuk sample/usr_puk_data.pem --bcl sample/bcl_data_for_sale_select.txt -c ${cipher_suite} # 數據部門審批后確認授權、并簽發BCL:ISSUER授權方簽名確認 ./genEncdbSQLCommand.sh -r BCL_ISSUE --issuer_sign --ipriv sample/usr_pri_data.pem --spuk sample/usr_puk_sale.pem --ipuk sample/usr_puk_data.pem --bcl sample/bcl_data_for_sale_select.txt -c ${cipher_suite}
銷售部門可以正確執行聯合查詢拿到密文計算結果。
說明如下命令需使用
ins_sale
用戶執行。SELECT * FROM person ps JOIN portrait pt ON ps.phone = pt.phone WHERE pt.have_car = encdb.enc_text_encrypt('Y',encdb.keyname_generate('ins_sale','demo', Null, Null, Null)); -- 可以查詢得到聯合查詢密文結果