端云互信SDK是一套基于TEE构建的数据安全传输工具,旨在保障端侧应用与云上服务,或云上服务之间的互相信任和数据安全传输。
端云互信SDK分为数据发送端(client)和数据接收端(server)两部分,其使用场景如下图所示。
支持语言 | 下载地址 | 使用指引 |
---|---|---|
Python | 点击前往Python | |
C++ | 点击前往C++ | |
Java | 点击前往Java | |
JS | 点击前往JS |
术语 | 含义 |
---|---|
TrustZone | TrustZone是ARM针对消费电子设备设计的一种硬件架构,TrustZone将硬件和软件资源划分为安全(Secure World)和非安全(Normal World)两个世界,所有需要保密的操作在安全世界执行,其余操作在非安全世界执行。 |
Secure World | TrustZone的安全区域 |
Normal World | TrustZone的非安全区域 |
TA | Trusted Application,运行在TEE安全区域中的服务 |
QSEE | 高通芯片的TrustZone方案 |
M-TEE | MTK芯片的TrustZone方案 |
注:只有注册过的应用才可以启用签名/验签功能,如果不需要签名字段,本步骤可省略。
进入端云互信一级目录,点击创建应用。输入合法的应用名称,应用描述;自定义应用的秘钥名称和信息,点击确定,创建成功后应用列表出现新增记录。
进入应用列表,按需查看PCC系统为应用自动创建的密钥,该密钥将应用于端云互信传输。
可在操作一栏对端云互信互信应用进行修改和删除,删除时需二次确认。
{ "ra_url": "open.volcengineapi.com", //火山引擎地址 "ra_service_name": "test_pcc", //接收端服务在Jeddak PCC上部署时的服务名称 "ra_policy_id": "16a371d7-130b-58eb-9e95-b5b816559ad8", //远程证明时的策略ID "ra_uid": "**", //用户的火山账号ID "bytedance_top_info": "{\"ak\": \"**\", \"sk\": \"**==\", \"service\": \"pcc_test\"}", // 用户火山账号的AK和SK信息 "attest_interval": 1800, //SDK自动做RA的时间间隔 "root_key_config": "{\"test_id_test_name\": \"./myPrivateKey.pem\"}" // 数据发送端对自己做签名时,给的appinfo和私钥文件地址 }
参数说明
{ .... "ra_attested_pods": [ { "cluster_id": "ccrqduf03q1qab0saeivg", "namespace": "default", "deployment": "jsc-server-example", "pod": "random" } ] .... }
参数说明
{ "tks_url": "open.volcengineapi.com", //服务端TKS服务地址 "tks_app_id": "2100278143", // TKS密钥的appid,一般等于用户的火山账号ID "tks_ring_id": "86aa20b9-bb5c-492f-a048-2fbceb1247b0", //密钥的密钥环ID "tks_key_id": "e1187037-e454-420e-a68f-4bac56fbdcc0", //密钥的keyid "bytedance_top_info": "{\"ak\": \"**\", \"sk\": \"**\", \"service\": \"pcc_test\"}", //访问TKS时,用户的火山账号信息 "refresh_interval": 600, //密钥刷新的时间间隔 "root_key_config": "[{\"app_info\": \"test_id_test_name\", \"pub_key\":\"./myPublicKey.pem\"}]" //数据发送端如果启用了身份签名,接收端进行验签时的公钥文件信息 }
参数说明
如果不启用验签功能,root_key_config可以不配置;
如果启用了签名,且已经在PCC的端云互信页面中注册了公钥,则pub_key可以不指定。
sdk_config_file_name = "./client_config.json" secure_channel_config = jsc.ClientConfig.from_file(sdk_config_file_name) secure_channel_client = jsc.Client(secure_channel_config)
env_conf_key = "***" secure_channel_config = jsc.ClientConfig.from_env(env_conf_key) secure_channel_client = jsc.Client(secure_channel_config)
secure_channel_client.attest_server()
test_msg = "我是待加密字符串" encrypted_msg, enc_key = secure_channel_client.encrypt_with_response(test_msg) # encrypted_msg 是加密后的密文 # send(encrypted_msg) 或直接解密encrypted_msg plaintext = enc_key.decrypt(encrypted_msg) print(plaintext) # plaintext = b"我是待加密字符串" # -------------------------------------------------------- test_msg = "我是待加密字符串" encrypted_msg = secure_channel_client.encrypt(test_msg) send(encrypted_msg)
test_msg = "我是待加密测试字符串" encrypted_msg, enc_key = secure_channel_client.encrypt_with_response(test_msg) plaintext = enc_key.decrypt(encrypted_msg) # 以上为对SDK的加解密功能做本地测试 # -------------------------------------------------------- # 以下为通过SDK实现端云互信的流程 test_prompt = "我是待加密prompt" encrypted_prompt, enc_key = secure_channel_client.encrypt_with_response(test_prompt) #端侧prompt加密 receive_response = send_to_server(encrypted_prompt) #将端侧密文prompt发送至云上 plaintext = enc_key.decrypt(receive_response) #端侧对收到的密文推理结果进行解密
src_file_name = "***" des_file_name = "***" enc_key = secure_channel_client.encrypt_file(src_file_name, des_file_name, "t") #t 是对文本文件按行加密,b 是对二进制文件整体加密
# 发送请求到服务端 test_msg = "我是待发送数据" encrypted_msg, enc_key = secure_channel_client.encrypt_with_response(test_msg) params = {"query": encrypted_msg} with requests.post(url=url, json=params, stream=True) as r: for line in r.iter_lines(): if line: res = line.decode().strip() enc_msg = base64.b64decode(res) plaintext = enc_key.decrypt(enc_msg) print("解密应答:", plaintext)
云云数据传输时或未启用签名时不需要关注该功能。
params: Dict[str, str] = {} params["enc_msg"] = secure_channel_client.encrypt(msg) params["app_info"] = app_info timestamp = str(int(datetime.now(timezone.utc).timestamp())) sign = secure_channel_client.gen_sign(app_info, timestamp) header = {"Timestamp": timestamp, "Sign": sign} response = requests.post(url, json=params, headers=header) 。。。
代码说明
压缩包包含 sln、vcxproj 项目文件、jsc 文件夹(源代码)、example 文件夹(示例程序)、thirdparty-src 文件夹(3 个依赖库源代码)、thirdparty-build 文件夹(OpenSSL 依赖库编译产物)。
prebuild.ps1 脚本介绍:这个脚本主要是用来解压 thirdparty 并编译 OpenSSL(编译产物在 thirdparty-build/openssl...,编译主项目时会用到)用户如果不需要重新编译OpenSSL,则不需要使用此脚本。
代码编译
依赖:
编译产物:
数据加密
example.cpp
数据加密
example.java
数据加密
example.ts
sdk_config_file_name = "./server_config.json" secure_channel_config = jsc.ServerConfig.from_file(sdk_config_file_name) secure_channel_server = jsc.Server(secure_channel_config)
env_conf_key = "***" secure_channel_config = jsc.ServerConfig.from_env(env_conf_key) secure_channel_server = jsc.Server(secure_channel_config)
# 获取请求参数 params = request.get_json() encrypt_msg = params.get("enc_msg") plaintext, encrypt_key = secure_channel_server.decrypt_with_response(encrypt_msg) plaintext = plaintext.decode() print("收到明文数据:", plaintext)
# 获取请求参数 params = request.form # save file encrypted_path = "./src_encrypted_file" file_1 = request.files["file1"] file_1.save(encrypted_path) # 解密文件 file_enc_key = params["file_enc_key"] # 文件加密的密钥信息 output_path = "./des_plaintext_file" secure_channel_server.decrypt_file(file_enc_key, encrypted_path, output_path, "t") #t 是对文本文件按行加密,b 是对二进制文件整体加密
# 获取请求参数 params = request.get_json() # 解密请求中的密文数据 encrypt_msg = params.get("query") plaintext, encrypt_key = secure_channel_server.decrypt_with_response(encrypt_msg) plaintext = plaintext.decode() print("收到请求数据:", plaintext) # 数据处理 res_data = "我是要返回给客户端的数据" # 发送响应 def generate_blocks(): for i in range(5): res_msg = encrypt_key.encrypt(res_data).encode() res_msg = base64.b64encode(res_msg).decode() yield f"{res_msg}\n" time.sleep(1) return Response(generate_blocks(), status=200, mimetype="text/plain")
# 获取请求参数 app_info = params.get("app_info") timestamp = headers.get("Timestamp") sign = headers.get("Sign") assert not secure_channel_server.verify_sign(app_info, timestamp, sign) == True