发布安全包含两类完全不同的问题
开发者经常把它们混在一起:
代码保护
减少发布包中的可读标识,增加逆向理解成本。
签名秘密保护
保护 .p12、密码、证书配置和发布 Profile,不让未授权人员生成可信发布包。
ArkGuard 解决第一类的一部分,不解决第二类。
开启混淆
≠
签名密码可以写进 build-profile.json5
一、HarmonyOS 项目中的两层构建配置
典型工程包含:
根 build-profile.json5
entry/build-profile.json5
根配置常用于产品、模块和签名配置;模块配置控制 ArkTS 构建与混淆。
项目模块中开启:
{
"apiType": "stageMode",
"buildOption": {
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"files": [
"./obfuscation-rules.txt"
]
}
}
}
}
}
配置本身可以进入仓库,但其中引用的规则和最终 Release 行为必须经过测试。
二、ArkGuard 能保护什么
根据华为官方说明,ArkGuard 源码混淆适用于:
- ArkTS;
- TypeScript;
- JavaScript。
主要能力包括:
- 名称混淆;
- 代码压缩;
- 注释删除;
- 保留白名单配置。
它不等于完整的软件防护方案,也不自动覆盖:
- C/C++;
- JSON/JSON5 配置;
- 图片和字符串资源;
- 写进配置文件的密码;
- 运行时已经解密的数据;
- 业务逻辑本身的安全缺陷。
所以不要在资源字符串里放秘密,然后期待“Release 已混淆”能够保护它。
三、保留规则应该从运行时可用性出发
当前规则示意:
# Keep entry points discoverable by the runtime.
-keep-global-name
-keep-property-name
较宽的保留规则有助于降低首次启用混淆时的运行风险,但也会减少混淆效果。
正确演进方式不是直接删除全部 keep,而是:
如果代码依赖字符串反射、动态属性名或外部协议字段,名称混淆可能改变运行行为。
四、JSON 序列化字段尤其需要关注
应用把状态序列化为 JSON:
const encoded: string = JSON.stringify(snapshot);
如果混淆策略改变对象属性名称,可能影响:
- 旧版本 Preferences 读取;
- 导出 JSON 的字段稳定性;
- 未来导入;
- iOS/HarmonyOS 数据交换;
- 用户自行查看备份。
因此持久化模型字段是协议的一部分,不能只看 Release 包能否启动。
建议准备一个固定样本:
Debug 保存 → Release 读取
Release 保存 → 重启读取
Release 导出 → JSON 字段检查
旧版本状态 → 新 Release 加载
五、签名配置中哪些内容是秘密
发布签名通常涉及:
- .p12 密钥库;
- 密钥库密码;
- Key Alias;
- 私钥密码;
- 发布 Profile;
- 数字证书路径。
其中公开证书本身未必是秘密,但私钥和密码必须保护;本机绝对路径也可能泄露用户名、目录结构和项目名称。
博客、截图和示例代码中只能使用明确占位符:
{
"storeFile": "<LOCAL_P12_PATH>",
"storePassword": "<SECRET>",
"keyAlias": "<KEY_ALIAS>",
"keyPassword": "<SECRET>",
"profile": "<LOCAL_PROFILE_PATH>",
"certpath": "<LOCAL_CERT_PATH>"
}
不要用一个“看起来像假的”真实密码做教程示例,因为读者无法判断它是否仍有效。
六、公共仓库应该保留什么
可以保留:
- 无签名的构建配置;
- 签名配置模板;
- 所需文件类型说明;
- 本地配置步骤;
- Release 构建命令;
- 不包含值的 Secret 名称。
不应保留:
- 实际密码;
- 私钥文件;
- 可直接使用的 .p12;
- 个人发布 Profile;
- CI 日志中的 Secret;
- 能恢复秘密的编码字符串。
即使仓库当前没有远端,也建议按“未来可能共享”管理。
七、.gitignore 不是秘密管理系统
.gitignore 只能阻止尚未跟踪的文件被新加入。
如果秘密已经提交:
后来加入 .gitignore
并不会从历史记录中删除它。
正确响应通常包括:
最重要的是轮换。只删除文件但继续使用同一秘密,不能消除已泄露风险。
八、自动检查只报告位置,不打印秘密
可以在发布前扫描敏感字段:
storePassword
keyPassword
BEGIN PRIVATE KEY
本地 .p12 路径
但日志应输出:
FAIL: potential signing secret in build-profile.json5
而不是把整行内容打印出来。
安全工具本身如果把秘密回显到 CI 日志,会制造第二次泄露。
九、Release 产物和调试资料要分开管理
构建目录可能包含:
- 签名或未签名安装包;
- Source Map;
- 名称映射;
- Symbol 包;
- 构建元数据。
发布到 AppGallery 的是指定产物,不代表整个 build/ 目录都应该公开。
Source Map 和混淆映射对崩溃定位很有价值,应安全保存并与版本号对应,但不建议随意上传到公开下载目录。
可以建立:
versionName + versionCode
→ 发布包
→ Symbol/Source Map
→ 构建时间
→ 证书版本
→ QA 结果
这样线上问题才能还原到准确构建。
十、混淆后的 Release 必须单独验收
Debug 通过不能代表混淆 Release 通过。
重点测试:
启动与页面
- EntryAbility 正常加载;
- 五个 Tab 正常;
- Builder 和 Symbol 资源正常。
持久化
- 读取已有 Preferences;
- 保存后冷启动恢复;
- 新旧字段兼容。
系统能力
- UserAuthenticationKit;
- DocumentViewPicker;
- 浏览器和邮件 Want;
- restartApp() 语言切换。
数据协议
- JSON 导出字段;
- CSV 内容;
- 日期 Key;
- 默认习惯稳定名称。
生命周期
- 冷启动;
- 后台回前台;
- 应用锁遮罩;
- 进程重建。
十一、发布命令也要避免泄露
不要在命令行中直接拼接密码,因为它可能出现在:
- Shell 历史;
- 进程列表;
- CI 日志;
- 截图;
- 错误报告。
优先使用 DevEco Studio 安全配置、受控本地文件或 CI Secret 注入机制。具体实现取决于构建环境,但原则是:
秘密只在需要的环境中可用
→ 不进入源码
→ 不进入日志
→ 不进入发布文章
十二、发布安全检查表
混淆
- Release 已启用预期 ArkGuard 配置
- 保留规则有明确原因
- 混淆后完整功能回归
- JSON 协议字段稳定
- Source Map/映射文件安全保存
签名
- 私钥和密码不在仓库
- 博客与截图全部使用占位符
- 本机绝对路径不出现在公开资料
- Profile 与 Bundle ID 一致
- 证书有效期已记录
泄露响应
- 自动扫描不回显秘密
- 曾提交的秘密已经轮换
- Git 历史、CI 日志和备份已检查
- 发布包来源可追溯
总结
HarmonyOS Release 安全需要同时处理:
混淆是发布工程的一部分,不是秘密管理的替代品,更不是应用安全的终点。
本文结合“心晴手记(MoodMemoir)”HarmonyOS 项目的 Release 构建与发布安全复盘整理,示例未包含任何真实签名信息。
参考资料
- HarmonyOS ArkGuard 混淆原理
- HarmonyOS 开发文档入口
网硕互联帮助中心





评论前必须登录!
注册