全加密云数据库可以用于多方数据融合计算,支持数据所有者授权第三方使用数据参与计算,实现联合营销等多种场景。
场景介绍
以某数据平台公司业务场景为例,该平台通过合法渠道,经用户授权后,收集了用户信息,生成用户画像表(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}
- 数据平台公司写入数据。
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}
- 保险公司销售部门查询数据。
- 销售部门未得到数据平台公司授权,使用数据平台公司数据:
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}
- 销售部门可以正确执行联合查询拿到密文计算结果。
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));
-- 可以查询得到联合查询密文结果