混淆是控制逆向可读性的基础手段。但一说混淆,很多团队想到的是“编译完了再用其他工具处理”,配置散落、排障麻烦、模块多了还容易出错。鸿蒙这边给了一套官方方案:ArkGuard 混淆直接作用在方舟字节码上,跟 DevEco Studio、Hvigor、HAP/HAR/HSP 打包天然绑定。开关在模块配置里,规则写在规则文件里,release 构建统一生效。
为什么值得开
ArkGuard 是官方工具链的一环,好处直接体现在开发流程里。
业务代码零侵入。开发阶段类名、方法名、文件名保持可读,不用为了交付安全牺牲源码质量。混淆只在 release 构建时统一执行,业务代码里不需要加任何混淆相关的标记。
真正理解 ArkTS 工程语义。ArkUI 组件属性、SDK API、Ability、Worker、HAR/HSP,这些概念通用混淆器不认识,经常“能构建但运行报错”。ArkGuard 内建规则和自动白名单覆盖了这些语义,开发者不用自己维护冗长的 keep 列表。
多模块交付更完整。obfuscation-rules.txt 管模块自身,consumer-rules.txt 管对外 API 保留,obfuscation.txt 随包发布。应用、源码库、字节码库的规则传递有统一路径,不用每个业务模块自己发明一套方案。
出了问题仍能定位。nameCache.json、sourceMaps.json、config.json 加上 hstack 形成可追溯链路。需要排查时按模块关掉混淆,通过映射文件确认名称变化,保护强度和可运维性不冲突。
零成本上手:两个配置加一次 release 构建
从 API 20 起,ArkGuard 混淆已集成到系统构建能力。三步搞定:
第一步,模块的 build-profile.json5
打开混淆开关:
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": ["./obfuscation-rules.txt"]
}
}
}
第二步,obfuscation-rules.txt
写入规则。总开关必须显式开启:
-enable-bytecode-obfuscation
新建工程时模板可能已经带了常见推荐项:
-enable-property-obfuscation -enable-toplevel-obfuscation -enable-filename-obfuscation -enable-export-obfuscation
第三步,用 release 构建。debug 构建不会做混淆。
排查行为差异时,不要只靠 debug/release 切换下结论。混淆开关用 ruleOptions.enable
控制,debug 和 release 还有其他差异。
混淆前后到底变了什么
用一段业务代码看效果。
混淆前,语义一眼可读:
class OrderHelper {
static orderId: string = ''
static createId(prefix: string): string {
OrderHelper.orderId = `${prefix}_20260725`
return OrderHelper.orderId
}
static printOrder(): void {
console.info(`[obfuscation-demo] ${OrderHelper.orderId}`)
}
}
OrderHelper、orderId、createId、printOrder——类职责和调用链完全暴露。
release 构建后,字节码中的等价效果:
class a {
static i: string = ''
static b(prefix: string): string {
a.i = `${prefix}_20260725`
return a.i
}
static c(): void {
console.info(`[obfuscation-demo] ${a.i}`)
}
}
业务逻辑和运行结果没变,但“订单工具类—创建订单号—打印订单”这条自解释的调用链,被压缩成了 a.b()、a.c()、a.i。工程里成百上千个类和方法同时转换,逆向阅读成本被系统性抬高。开发侧仍然只维护原始的高可读源码,这就是字节码阶段统一混淆的价值。
映射文件 nameCache.json
记录了原始名和短名的对应关系。它的结构不是简单的扁平字典,会按文件、方法、属性分别记录。排障时对着查就行。
keep 规则怎么用
不是所有名字都该被混淆。属性被动态访问、文件名被动态引用,这些场景需要 keep。
典型错误:静态属性 orderId
被混淆成了短名,但代码里用字符串拼出来动态访问,直接运行失败。这时候要加:
-keep-property-name orderId
文件名类似。动态 import、routerMap、pushUrl 这类以路径字符串跳转的场景,文件名必须 keep。正确写法是只写名称组件,不写完整路径:
-keep-file-name OrderDetail
HAR/HSP 库模块则通过 consumer-rules.txt
保留对外 API。注意区分:本地 HAR 和发布态源码 HAR 会跟随使用方模块一起混淆,字节码 HAR 只在构建它那一次做混淆,不会二次处理。
按顺序开启,一步步来
推荐顺序:
- 先开
-enable-bytecode-obfuscation - ,跑通 release
- 再开 top-level 混淆
- 再开属性混淆,静态/动态访问的属性加 keep
- 再开导出混淆,HSP/HAR 对外接口加 keep
- 最后开文件名混淆,动态引用路径加 keep
每开一步做一次功能回归。报错了先查 nameCache.json
和 config.json
,用最短 keep 列表修复,不要一上来就加几百行白名单。DevEco 的 ObfuscationHelper 能扫描推荐白名单,动态字符串场景仍需人工复核。
发布时本地备份 obfuscation 目录和 sourceMaps。线上报混淆堆栈,用 hstack 还原。
从基础混淆到纵深防护
ArkGuard 名称混淆适合作为 release 的常态化基础防线,默认纳入构建流水线。对安全等级更高的应用,再叠加应用加密和应用加固,形成从语义保护到交付物保护的纵深体系。两个动作覆盖核心语义信息,比外挂流水线省事得多。
重庆华鸿科技 深耕鸿蒙生态人才培养,推出《HarmonyOS 应用开发者认证培训班》《HarmonyOS 应用开发者原生开发精研班》《HarmonyOS 原生应用项目实战与就业班》,由华为官方认证讲师授课,手把手带您从零构建商业级鸿蒙应用。
课程亮点:真实项目驱动,以办公、社交、工具类 App 为案例;小班精讲,每位学员获得针对性指导;就业直推,合作企业覆盖西南地区鸿蒙生态链,优秀学员直接内推。