全密態數據庫可以用于個人隱私保護,防止用戶隱私泄露,本文介紹將全密態數據庫用于個人隱私保護的最佳實踐。
場景介紹
以某保險公司業務場景為例,保險公司投保人員信息表(person)如下,記錄了用戶隱私數據,現需對這些隱私數據進行加密:
姓名(name) | 手機號(phone) | 身份證號(ID) | 銀行卡號(debit_card) | 家庭住址(address) |
淘小寶 | 13900001111 | 111222190002309999 | 6225888888888888 | 杭州市ABC路888號 |
釘三多 | 13900002222 | 111222190002308888 | 6225666666666666 | 杭州市DEF路666號 |
上表中數據僅為示例。
保險公司投保人員信息表中,投保人員敏感信息在離開手機端時,被數據部門加密保護。銷售部門、應用服務以及數據庫側只能看到密文數據,無法泄露投保人員隱私數據。
用戶可以通過保險公司手機APP,對數據進行加密后,寫入或者更新個人信息。
保險公司銷售部門直接連接查詢數據庫,僅能看到數據密文,看不到明文內容。
前提條件
已完全了解并掌握全密態數據庫的基本使用,更多信息請參見產品概述。
已下載并配置全密態數據庫提供的客戶端SDK或JDBC,更多信息請參見客戶端使用說明。
已下載EncDB Tool工具,該工具主要用于輔助完成用戶主密鑰導入、證書(公私鑰對)注冊、BCL簽發和撤銷等操作。
EncDB Tool工具基于傳入參數,生成可直接在數據庫中執行的SQL命令。您可以將EncDB Tool工具下載并解壓后,使用
./genEncdbSQLCommand.sh --help
命令查看更多解釋。說明BCL的更多信息,請參見授權多用戶訪問。
準備工作
本文以CentOS環境為例進行命令配置。
密碼套件配置。
配置密碼套件變量。
cipher_suite=RSA_WITH_AES_128_CBC_SHA256
生成文件模板。
說明本示例基于文件模板,通過如下命令在sample目錄下生成后續示例所需要的配置文件,其中包括用戶密鑰文件、授權文件等。
./generateSampleKeyAndBCLs.sh -c ${cipher_suite}
初始化數據庫。
創建數據庫。
CREATE DATABASE demo;
說明本文以
demo
為例,您可以根據實際情況命名數據庫,請注意在后續命令中進行同步修改。在數據庫下創建全密態數據庫擴展。
CREATE EXTENSION encdb;
獲取全密態數據庫集群公鑰證書并寫入到本地文件中。
SELECT encode(db_process_msg_api('{"request_type":0,"version":"1.2.8"}'),'escape')::json->'server_info'->'public_key'
說明本文以本地文件default_enclave_public_key.pem為例進行演示,您可以根據實際情況命名本地文件,請注意在后續命令中進行同步修改。
公鑰證書內容不包含頭尾
""
。
轉換為標準公鑰證書文件格式。
執行以下命令將
\\n
替換為換行符(\n
):sed -i 's/\\\\n/\n/g' default_enclave_public_key.pem
執行以下命令去除所有空行:
sed -i '/^[ ]*$/d' default_enclave_public_key.pem
個人隱私保護流程示例
保險公司數據部門
保險公司數據部門準備投保人員信息。
-------- 創建用戶 -------- -- 數據部門,對用戶數據負責 CREATE USER ins_data; -- 銷售部門 CREATE USER ins_sale; -------- 創建表 -------- -- 為數據部門創建投保人員信息表 CREATE TABLE person ( name enc_text, phone enc_text, ID enc_text, debit_card enc_text, address enc_text ); -- 授權數據部門訪問數據表 GRANT ALL ON person TO ins_data;
注冊保險公司數據部門用戶。
說明EncDB Tool工具將會基于傳入的參數自動生成SQL語句,您需要將生成的SQL在數據庫中執行。
./genEncdbSQLCommand.sh -r MEK_PROVISION --mek sample/default_mek_data.bin -e default_enclave_public_key.pem -c ${cipher_suite} # 獲取數據部門賬號MEKID,可以通過SQL查詢獲得:SELECT encdb_get_current_mek_id(); # 本文以178079820457738240為例 mekid_data=178079820457738240 ./genEncdbSQLCommand.sh -r BCL_REGISTER --mekid ${mekid_data} --mek sample/default_mek_data.bin --puk sample/usr_puk_data.pem --pri sample/usr_pri_data.pem -c ${cipher_suite}
保險公司數據部門為投保信息表創建加密密鑰。
說明如下命令需使用
ins_data
用戶執行。命令中的
encdb.dek_xxx()
和encdb.keyname_xxx()
為類型轉換函數,更多用法,請參見類型轉換函數說明。
-- 創建dek,記錄groupid,例如 b6785611-0c49-4f13-87a9-13f151de9b4d SELECT encdb.dek_generate(encdb.keyname_generate('ins_data','demo','public','person','name')); -- 此處僅為示例,同步給所有列,即共用一個dek SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ins_data','demo','public','person','phone'),encdb.keyname_generate('ins_data','demo','public','person','name')); SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ins_data','demo','public','person','ID'),encdb.keyname_generate('ins_data','demo','public','person','name')); SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ins_data','demo','public','person','debit_card'),encdb.keyname_generate('ins_data','demo','public','person','name')); SELECT encdb.dek_copy_keyname(encdb.keyname_generate('ins_data','demo','public','person','address'),encdb.keyname_generate('ins_data','demo','public','person','name'));
正常情況下,不允許用戶直接通過SQL加密數據(不安全),用戶需要明確授權該行為。
編輯BCL內容,將目標dek的授權范圍(包括groupid)更新到BCL中。
./setGroupIdBCL.sh -d b6785611-0c49-4f13-87a9-13f151de9b4d
說明本示例中的
b6785611-0c49-4f13-87a9-13f151de9b4d
僅為示例,實際取值請從如下命令中獲取:SELECT encdb.dek_generate(encdb.keyname_generate('ins_data','demo','public','person','name'));
簽發BCL。
./genEncdbSQLCommand.sh -r BCL_ISSUE --subject_sign --spriv sample/usr_pri_data.pem --spuk sample/usr_puk_data.pem --ipuk sample/usr_puk_data.pem --bcl sample/bcl_for_data_insert.txt -c ${cipher_suite} ./genEncdbSQLCommand.sh -r BCL_ISSUE --issuer_sign --ipriv sample/usr_pri_data.pem --spuk sample/usr_puk_data.pem --ipuk sample/usr_puk_data.pem --bcl sample/bcl_for_data_insert.txt -c ${cipher_suite}
保險公司數據部門寫入數據。
說明如下命令需使用
ins_data
用戶執行。INSERT INTO person VALUES(encdb.enc_text_encrypt('淘小寶',encdb.keyname_generate('ins_data','demo','public','person','name')), encdb.enc_text_encrypt('13900001111',encdb.keyname_generate('ins_data','demo','public','person','phone')), encdb.enc_text_encrypt('111222190002309999',encdb.keyname_generate('ins_data','demo','public','person','ID')), encdb.enc_text_encrypt('6225888888888888',encdb.keyname_generate('ins_data','demo','public','person','debit_card')), encdb.enc_text_encrypt('杭州市ABC路888號',encdb.keyname_generate('ins_data','demo','public','person','address'))); INSERT INTO person VALUES(encdb.enc_text_encrypt('釘三多',encdb.keyname_generate('ins_data','demo','public','person','name')), encdb.enc_text_encrypt('13900002222',encdb.keyname_generate('ins_data','demo','public','person','phone')), encdb.enc_text_encrypt('111222190002308888',encdb.keyname_generate('ins_data','demo','public','person','ID')), encdb.enc_text_encrypt('6225666666666666',encdb.keyname_generate('ins_data','demo','public','person','debit_card')), encdb.enc_text_encrypt('杭州市DEF路666',encdb.keyname_generate('ins_data','demo','public','person','address')));
保險公司數據部門查詢數據。
直接查看信息表,查詢結果均為密文。
SELECT name,phone FROM person; name | phone --------------------------------------------------------------------------+-------------------------------------------------------------------------- \xdf4901df087c6a3e0325175bb76942c684191a8dda2a8d0c35f295dc1e30eaeaa0c0e3 | \x315102ea5ab8a659066ab672e6dfbfd89a3a2b360bf6efe3787931e00f61af05f7408c \xed4903dfd1bda1a89ad6aa7e8905c0e6305e15db4bc9ce2d2cfac9e25094d2a3ed367d | \xd75bb76942c682a8d0c35f295dc5ab8a659066ab672e6de00f61af0a1a89ad6aa7e890 (2 行記錄)
使用
ins_data
用戶執行如下命令,查詢結果為明文。SELECT encdb.decrypt(name) FROM person WHERE name LIKE encdb.enc_text_encrypt('淘%',encdb.keyname_generate('ins_data','demo','public','person','name')); decrypt --------- 淘小寶 (1 row)
保險公司銷售部門
注冊保險公司銷售部門賬號。
說明EncDB Tool工具將會基于傳入的參數自動生成SQL語句,您需要將生成的SQL在數據庫中執行。
./genEncdbSQLCommand.sh -r MEK_PROVISION --mek sample/default_mek_sale.bin -e default_enclave_public_key.pem -c ${cipher_suite} # 獲取銷售部門賬號MEKID,可以通過SQL查詢獲得:SELECT encdb_get_current_mek_id(); # 本文以2715553450389700608為例 mekid_sale=2715553450389700608 ./genEncdbSQLCommand.sh -r BCL_REGISTER --mekid ${mekid_sale} --mek sample/default_mek_sale.bin --puk sample/usr_puk_sale.pem --pri sample/usr_pri_sale.pem -c ${cipher_suite}
保險公司銷售部門查詢數據。
銷售部門未得到數據部門授權,無法查看數據內容,投保人員隱私數據得到保護。
直接查看信息表,查詢結果均為密文。
SELECT name,phone FROM person; name | phone --------------------------------------------------------------------------+-------------------------------------------------------------------------- \xdf4901df087c6a3e0325175bb76942c684191a8dda2a8d0c35f295dc1e30eaeaa0c0e3 | \x315102ea5ab8a659066ab672e6dfbfd89a3a2b360bf6efe3787931e00f61af05f7408c \xed4903dfd1bda1a89ad6aa7e8905c0e6305e15db4bc9ce2d2cfac9e25094d2a3ed367d | \xd75bb76942c682a8d0c35f295dc5ab8a659066ab672e6de00f61af0a1a89ad6aa7e890 (2 行記錄)
說明如果出現
ERROR: permission denied for table person
的錯誤時,執行GRANT SELECT ON person TO ins_sale;
授權訪問表。使用
ins_sale
用戶執行如下命令,提示未進行BCL授權。SELECT encdb.decrypt(name) FROM person; WARNING: -- encdb -- -- Untrusted log -- 4 - src/core/untrusted/src/encdb_untrusted_enclave.cpp,256,encdb_ecall: Select BCL (subject_mekid: 2715553450389700608, issuer_mekid: 178079820457738240) from table fail - returned 0xfa030000 ERROR: encdb_ext_enc_text_decrypt: enc_text decrypt errno:fa030000