INTEGRATION · 0.5.0

DeviceTrust 接入手册

先在工作台创建应用,再连接 Android SDK 与业务服务。应用密钥只保存在业务服务端。

01 / 接入准备

入口地址
工作台https://devicetrust-console.lingzidev.com
业务与上报 APIhttps://devicetrust-sdk-api.lingzidev.com
版本Android SDK 0.5.0 / Android 7.0+ / 四种 ABI
  1. 在“应用管理”创建应用,包名填写 Android applicationId。
  2. 保存创建时展示的应用 ID 与应用密钥,后者只展示一次。
  3. “接入保护”默认开启签名上报。硬件证明需要配置 APK 证书 SHA-256,再开启并进行目标机型验收。
  4. 策略先使用观察模式评估风险;确认业务处置已接入后切换执行模式。

02 / Android SDK

下载 SDK 包,将 sdk-0.5.0.aar 和 sdk-secure-0.5.0.aar 放入 app/libs。可选模块独立引入;安全模块包含已经混淆的原生库。

// app/build.gradle
dependencies {
    implementation files('libs/sdk-0.5.0.aar')
    implementation files('libs/sdk-secure-0.5.0.aar')
    // 可选:sdk-environment、sdk-rootbeer
    // RootBeer 适配还需 com.scottyab:rootbeer-lib:0.1.2
}

在用户同意采集后,于后台线程调用。challenge 由你的业务服务创建后返回 App,businessToken 是业务登录会话;完整在线体验代码在 SDK 包 examples 中。

String api = "https://devicetrust-sdk-api.lingzidev.com";
String[] pins = {"AU7LGDAFJUgs4HkcpRf1O7/6OU9avVMvle6wTsAK5m4="};
String keyId = SecureReporter.keyId(context, appId);
// 将 keyId 提交给业务服务,取得绑定本次业务的 challenge。
JSONObject report = DeviceTrust.collect(context,
    new DeviceTrust.Options(appId, false), true);
JSONObject result = SecureReporter.upload(
    context, api, pins, challenge, report);
String reportId = result.getString("reportId");
// reportId 回传业务服务进行事件评估与执行授权。

导入 com.device.trust.DeviceTrust 与 com.device.trust.secure.SecureReporter。SDK 会生成 Keystore 密钥、注册证明并提交二进制帧。密钥注册过期时,服务端下发新注册挑战。pin 为 API 证书 SPKI 的 SHA-256/Base64,证书公钥轮换需先发布包含新旧 pin 的 SDK 配置。

业务接口与防重放

设备 ID 只标识已登记密钥,不能直接授权业务。SDK 通过 SecureReporter.deviceId(context, appId) 读取服务端登记 ID;签名密钥复用期间 ID 保持,同型号设备分别持有 ID。

业务服务器必须认证当前账号,将接口方法、路径、订单、金额、币种、收款对象等完整业务意图规范化后计算 SHA-256,保存为 requestHash。该摘要由业务服务器生成,不能信任客户端传入的摘要。

挑战与事件的 context.requestHash 保持一致;执行前在 /v1/decisions/claim 顶层提交当前请求重新计算的 requestHash。换账号、改金额或换目标就不能使用旧授权。同一操作重复请求在业务数据库按 operationId 唯一约束去重,支付渠道使用同一幂等键。

SDK 下载包包含 Go 服务端 businessguard 接入组件,会核对请求摘要、操作、应用、事件、执行模式和到期时间。它应放在真实业务处理函数中,取得授权后才提交业务效果。完整资源验真与联调限制见下载包 docs/environment-0.5.md。

03 / 业务服务端

所有业务接口使用 Authorization: Bearer <应用密钥>。账号、订单和金额来自业务服务,不采用客户端自报值。eventId 在应用内唯一,并持久保存以支持重试。

POST /v1/challenges
Content-Type: application/json
Authorization: Bearer <APP_KEY>

{
  "appId": "APP_ID",
  "eventId": "registration-20261111-001",
  "accountId": "ACCOUNT_ID",
  "type": "register",
  "clientIp": "203.0.113.10",
  "context": {"requestHash": "REQUEST_SHA256"},
  "keyId": ""
}

首次 keyId 为空,其后填写 SDK 返回的 keyId。挑战有效期 3 分钟,将响应原样交给 SDK。得到 reportId 后,使用原挑战的账号、类型、IP 与上下文提交:

POST /v1/events
Authorization: Bearer <APP_KEY>

{
  "appId": "APP_ID",
  "eventId": "registration-20261111-001",
  "reportId": "REPORT_ID",
  "accountId": "ACCOUNT_ID",
  "type": "register",
  "clientIp": "203.0.113.10",
  "context": {"requestHash": "REQUEST_SHA256"}
}

type 为 register、reward、payment 或业务自定义事件类型。营销 context 使用 campaignId、recipientId;支付使用 orderId、paymentMethodId、amountMinor、currency。金额按最小货币单位。支付工具和收款对象使用业务侧去标识化代号,不上传完整卡号。响应包含 score、action、mode、reasons 与策略版本;action 为 observe、verify、hold。

04 / 连接实际处置

执行模式下,核验或暂缓事件须先取得批准。业务服务应在完成真实核验后提交结果,或交由工作台审批。

POST /v1/decisions/resolve
{"appId":"APP_ID","eventId":"EVENT_ID",
 "resolutionId":"VERIFY_RESULT_ID","status":"approved"}

POST /v1/decisions/claim
{"appId":"APP_ID","eventId":"EVENT_ID",
 "operationId":"BUSINESS_OPERATION_ID","requestHash":"REQUEST_SHA256"}

POST /v1/executions
{"appId":"APP_ID","eventId":"EVENT_ID",
 "operationId":"BUSINESS_OPERATION_ID","token":"CLAIM_TOKEN",
 "receiptId":"RECEIPT_ID","status":"succeeded",
 "reference":"BUSINESS_REFERENCE"}

上述请求都需要应用密钥。claim 的 token 与 expiresAt 是执行凭据,首次领取限事件或批准后 5 分钟内;业务必须检查到期时间,在自己的数据库按 operationId 原子幂等提交。相同授权重试用于恢复回执,不启动第二次业务效果。支付真实回调通过 /v1/outcomes 进行结果回流,字段见下载包 integration.md 与 business-risk.md。

05 / 签名与设备真实性

TLS 校验证书链、主机名和 SPKI;设备报告使用 DTP4 二进制帧、P-256 ECDH、HKDF-SHA256、AES-256-GCM 和 SHA256withECDSA。签名覆盖头与密文,服务端将挑战绑定到账号和业务。NDK 编排密码调用,Keystore 私钥不导出,四架构原生库经 xollvm 混淆。

signature_only 表示持钥签名;tee/strongbox 表示通过硬件证明。硬件证明校验可信根、撤销状态、挑战、启动锁定、包名和 APK 签名。证明反映注册时状态,不保证其后所有信号真实。设备被完全控制时,混淆与固定证书也不能保证绝对不可抓包。完整帧格式与约束见 SDK 包 secure-protocol.md。

06 / 在线体验

  1. 下载并安装体验 APK,默认服务已配置,无需 USB 端口转发。
  2. 用管理员提供的体验密码登录,账号填写自选测试名称;同意采集后尝试注册、奖励或支付。
  3. 进入工作台查看事件。遇到等待核验/审核,在事件详情处理,再回 App 点“查询并继续”。
在线体验使用独立应用与演示账本。真实项目请创建自己的应用并接入自己的账号、核验与支付服务。当前尚待 APK 真机与目标硬件证明矩阵验收。

07 / 排查与重试

状态处理
401检查业务应用密钥或登录会话。
403查看原始 error:证明、业务绑定、停用密钥或审批状态不满足。
409同一 ID 已用于不同内容,修正幂等数据,不能覆盖旧记录。
410挑战、注册或授权过期,按对应流程重新发起。
TLS / pin mismatch核对服务域名、证书链与 SPKI,不能关闭证书验证。

服务端原始错误会保留。记录 eventId、reportId、发生时间和完整错误,排查时避免附带应用密钥或用户敏感信息。