本文基于 HarmonyOS 7(API 26)官方《星盾机密风控引擎》开发指导、RiskControlEngine API 参考与官方最佳实践整理。文中代码改写自官方示例并加了V哥自己的注释,接口名均为官方文档核验过的真实名称;选题原标"⚠️ 待核实(安全类能力可能仅对特定类目开放)",V哥动笔前专门做了核验,结论见正文第一节——能力公开,但需在 AGC 申请开通并通过审批。涉及真机表现的部分以真机实测为准,未做任何实测数据编造。


HarmonyOS 7 星盾机密风控实战

引子:风控的悖论

V哥先讲一个所有做金融类应用的人都懂、但很少说透的悖论:做风控,需要数据;做合规,不能碰隐私。

传统做法是两条路,各有各的疼。第一条路:把设备环境、用户行为这些数据打包上传到云上风控引擎,模型算得欢,但用户的敏感数据出了设备——隐私评估这一关越来越难过。第二条路:全端侧规则,数据哪儿都不去,但规则写死在客户端里,被逆向一拆,防诈策略对黑产透明,等于裸奔。

这个悖论在 HarmonyOS 7(API 26)上有了官方答案:星盾机密风控引擎。官方新能力一览里那句话值得逐字读(HarmonyOS 7 新能力一览):

设备风险因子仅在端侧本地机密空间使用进行融合计算设备风险,数据"可用不可见",用于银行转账、支付交易风控场景。

V哥的概括:数据能用,但拿不走;风险能算,但看不见。 这一期把这套机制拆开讲:先说清楚它到底开放到什么程度(核验结论),再拆"可用不可见"的架构,然后四步接入写代码,最后给一份接入前自检清单。


一、先核验再动笔:这套能力开放到什么程度

安全类能力最容易"发布会很热闹、文档里找不到"。V哥动笔前把官方材料翻了一遍,先给核验结论:

核验项结论出处
起始版本API 26.0.0(HarmonyOS 7)开始支持,需升级至 HarmonyOS 7 并以实际支持机型为准开发指导
所属 KitDevice Security Kit(设备安全服务),模块名 riskControlEngineAPI 参考
接口是否公开公开。importRiskFactorsgetRiskControlResult 均在 API 参考中列出,且支持元服务、仅限 Stage 模型同上
准入条件需在 AGC(AppGallery Connect)申请开通"星盾机密风控引擎"服务权限并完成审批;风险因子注册与风控策略配置审批通过后才能启用并下发端侧官方最佳实践
设备范围Phone、Tablet、PC/2in1;不支持的设备返回错误码 801(Capability not supported)同上
调用频次每个应用在单台设备上,每天最多调用 10 次开发指导

把"⚠️ 待核实"那条钩子正式摘掉:V哥没有核到"仅金融类目开放"的硬性限制,官方最佳实践的示例场景确实是通联类应用 + 金融类应用的联防联控,但能力描述本身面向的是"应用"——真正的门槛不在类目,而在AGC 审批:你得先注册风险因子、配置风控策略,审批过了才能下发到端侧跑。换句话说,这套能力不是接个 SDK 就完事,策略本身要走审核。这一点,做接入排期的同学要提前心里有数。


二、"可用不可见"到底怎么实现:云侧管理 + 端侧执行

官方最佳实践给了一句架构定语:“云侧管理 + 端侧执行”最佳实践)。V哥拆成两半讲。

云侧管什么: 应用在云侧管理台注册应用风险因子、配置风控策略规则,启用后策略配置加密下发至端侧设备。注意方向——下发的是策略,不是数据采集,云端从头到尾拿不到用户的原始风险数据。

端侧算什么: 端侧在机密计算空间里接收风险因子和策略配置,应用通过 riskControlEngine.importRiskFactors() 写入业务风险因子,调用 riskControlEngine.getRiskControlResult() 执行策略规则,输出风险评估结果。

"可用不可见"官方拆成了三句话,V哥认为这三句话就是整个引擎的产品哲学:

  • 可算不可取:系统与应用的风险因子,应用可以用于策略规则的计算,但无法把数据拿出到系统外;
  • 可知不可见:应用可以知道因子的意义,但看不到其明文内容;
  • 可用不泄露:风控策略或风控数据在计算和使用过程中,不会被逆向泄露出去。

第三句是给第二条路(端侧规则裸奔)的正面回答——策略加密下发、在机密空间内执行,黑产逆向你的 APK 也拆不出规则。

整套链路V哥画成一张图:

可用不可见链路

还有一层容易被忽略的价值:联防联控。官方最佳实践的典型场景里,通联类应用(检测到用户存在被诈骗风险)把风险因子写入端侧机密空间并授权给金融类应用,金融类应用在转账节点融合"通联类因子 + 系统因子(如安装未知应用)+ 自有因子(如首次向陌生账户转账)"综合研判。以前你的风控只能看自己一亩三分地的数据,现在系统在端侧机密空间里帮你把邻居的情报串起来了——且串的过程谁也看不见明文。


三、动手:四步接入

前置动作先做两件:在 AGC 控制台开通 Device Security 服务里的"星盾机密风控引擎"开关,并申请 Profile(官方开发指导的"说明"里明确要求);然后在云侧管理台注册风险因子(如 isFirstTransfer)和策略(如 antiFraudRiskEvaluation),等审批通过。下面的代码改写自官方示例,factorNamepolicyName 要换成你自己注册并通过审批的名称。

第一步:生成 nonce

调用两个接口都要传 nonce,返回结果会带回这个值用于请求-响应配对,官方明确说这是防重放攻击的手段。硬性要求:16 至 66 字节,base64 编码范围,推荐每次都从服务器随机生成新值。

// 生成 nonce:官方推荐 32 字节随机数 + Base64 编码
// V哥提醒:nonce 是请求的"防重放身份证",别用固定值,别客户端写死
let rand = cryptoFramework.createRandom();
let randData = rand.generateRandomSync(32);
let base64 = new util.Base64Helper();
let nonce: string = base64.encodeToStringSync(randData.data);

第二步:导入 App 专属风险因子

风险因子写入分两类:应用自有因子靠主动调用接口写入,时机由业务自己控制;系统因子已预制在端侧,系统检测到风险事件时自动更新,不用你管。

import { riskControlEngine } from '@kit.DeviceSecurityKit';

// 把应用自有风险因子写入端侧机密计算空间
// factorName 必须是你在云侧注册并审批通过的名称
async function importFactors(nonce: string): Promise<void> {
  let data: riskControlEngine.ImportData = {
    appFactorData: [
      { factorName: 'isFirstTransfer', factorValue: true }  // 示例:首次转账
    ],
    nonce: nonce
  };
  try {
    await riskControlEngine.importRiskFactors(data);
  } catch (error) {
    let e: error.BusinessError = error as error.BusinessError;
    console.error(`importRiskFactors failed: ${e.code}, ${e.message}`);
  }
}

因子值的类型是 ValueType = number | boolean | string,长度上因子名 1 到 255 字节。V哥的实践建议:因子设计在审批阶段就要一次想全——每个因子都要注册、审核,事后补一个因子就是再走一轮流程。

第三步:发起风控评分

官方明确说:可以跳过第二步直接调评分接口(只用系统因子出结果),也可以导入因子后做综合研判。

// 在支付/转账节点调用,传入策略名,拿端侧机密空间的评分结果
async function getRiskResult(nonce: string): Promise<string> {
  const request: riskControlEngine.RiskControlDetectionRequest = {
    policyName: 'antiFraudRiskEvaluation',  // 必须是已注册并审批的策略名
    nonce: nonce
  };
  try {
    let res: riskControlEngine.RiskControlDetectionResponse =
      await riskControlEngine.getRiskControlResult(request);
    return res.result;  // JWS 格式字符串,别直接用
  } catch (error) {
    let e: BusinessError = error as BusinessError;
    console.error(`getRiskControlResult failed: ${e.code}, ${e.message}`);
    return '';
  }
}

第四步:服务端验证 JWS

返回值是 JWS(JSON Web Signature)格式,官方的流程要求在应用服务器上验证,不是端侧拿来就用:

  1. 解析 JWS 得到 Header、Payload、Signature。Header 里 alg 为 ES256(SHA256withECDSA),x5c 是三级证书链:x5c[0] 为签名证书,x5c[1] 为华为设备二级 CA,x5c[2] 为华为设备 ROOT CA;
  2. 用官方提供的 Huawei CBG Device Attestation Root CA 证书 验证证书链,确认 x5c[0] 的 Common Name 为 Harmony OS Device Attestation Service;
  3. 校验签名,再从 Payload 里取结果:nonce 回传比对 + RiskDetectionOutput.result 风控评分。

Payload 里的 result 官方示例是一个分值(如 “1”~“3” 对应不同风险等级,具体映射由你在云侧策略配置里定义),业务侧按等级走差异化动作:放行、二次核验、拦截。阈值和映射是你在管理台里配的,不是引擎替你定的——这正是"开发者可自定义防诈策略"的含义。


四、V哥的两个判断

判断一:每天 10 次的配额,逼你把风控当稀缺资源设计。 这是V哥的自创观点:大多数团队接风控 API 的习惯是"关键动作都查一遍",登录查、下单查、支付查。但星盾机密风控引擎单设备单应用每天 10 次的官方限额,物理上否决了"到处都调"的思路。V哥认为这反而是好事——它逼你像设计埋点体系一样设计风控调用点位:哪些节点真正值得消耗一次配额?V哥的原则是只挂在"不可逆动作"上(转账、支付、改绑手机),可逆动作靠本地轻量规则兜底。配额在此不是限制,是帮你砍需求的刀。

判断二:策略文件会成为新的业务资产。 以前风控逻辑散落在服务端代码里,跟着版本发布走;现在策略在云侧配置、审批、加密下发端侧执行——它有了独立的生命周期。V哥建议把策略配置像数据库 schema 一样管理起来:版本化、变更留痕、和风控运营同学明确Owner。审批制意味着策略改一次不是改一次代码,是走一次流程,策略设计的前置投入必须加大


五、接入前自检清单

#检查项挂了会怎样
1AGC 已开通"星盾机密风控引擎"开关并申请 Profile?接口直接调不通
2风险因子与策略已在云侧注册且审批通过?factorName/policyName 无效,策略不下发
3目标设备覆盖 Phone/Tablet/PC/2in1?其他设备处理 801 错误码?部分机型直接崩体验
4nonce 每次随机、16-66 字节、base64 范围?重放攻击风险,结果不可信
5返回的 JWS 在服务端验签后才使用?结果可被伪造,风控形同虚设
6调用点位设计过配额(每天 10 次)?高峰期静默失败
7已知真机表现待验证?风控评分表现以真机实测为准上线后才发现体验问题

补充一句:模拟器与不支持设备上的表现、风险识别的准确率表现,官方文档未给出量化数据,一律以真机实测为准,V哥不做编造。


六、收尾:风控的下一步,是"不碰数据的风控"

回头看,星盾机密风控引擎真正改变的不是某个接口,而是风控工程的前提假设:数据必须在场,才能参与计算——这个假设被端侧机密计算空间推翻了。数据在机密空间里算完,出来的只有一个 JWS 签名的评分结果,原始因子从头到尾没有出端。

对开发者,这意味着三件事要做在前头:AGC 审批流程提前启动、因子和策略一次设计到位、调用点位按配额精打细算。对行业,V哥愿意给一个更大的判断:当"可用不可见"成为系统能力,隐私合规和风控效果这对老冤家,第一次坐在了同一边——这不是权衡,是解耦。

7.0 刚发,能走完 AGC 审批、把策略真正下发到端侧的团队还在少数。金融、支付、涉交易的应用,这一课早补早安心。


参考与出处

本文涉及的机制、接口与准入条件来自以下官方文档:


最后一句:以前做风控是把数据请出门再请回来,现在数据根本不出门——把策略当资产经营,把配额当预算花,转账按下的那一刻,风险在用户看不见的机密空间里已经被算完了。

Logo

讨论HarmonyOS开发技术,专注于API与组件、DevEco Studio、测试、元服务和应用上架分发等。

更多推荐