Appearance
10_Engineering/11 - 源码保护
1. 源码保护概述
HarmonyOS 提供多层次的应用源码保护机制,防止应用被反编译、篡改和逆向工程。
1.1 保护层级
| 层级 | 保护方式 | 防护目标 |
|---|---|---|
| 第一层 | 字节码混淆 | 提高逆向难度 |
| 第二层 | ByteCodeHAR 保护 | 保护 HAR 模块源码 |
| 第三层 | 代码签名 | 防止 APK 被篡改 |
| 第四层 | AntiTamper 检测 | 检测应用是否被篡改 |
| 第五层 | 敏感数据加密 | 保护密钥/证书 |
2. ByteCodeHAR 保护
2.1 ByteCodeHAR 是什么
ByteCodeHAR(.bc HAR)是 HarmonyOS 特有的字节码级 HAR 保护机制。
| 特性 | 说明 |
|---|---|
| 保护方式 | 将 ArkTS 源码编译为字节码(.bc),而非源码(.ets) |
| 保护强度 | 比源码级 HAR 更高,无法直接反编译为 ArkTS |
| 适用场景 | 核心业务逻辑、算法、加密模块 |
| 文件格式 | .bc(ArkTS ByteCode) |
2.2 配置 ByteCodeHAR
json5
// entry/build-profile.json5
{
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"includes": ["**/*.ets"],
"excludes": [
"**/model/*.ets",
"**/config/*.ets"
]
},
"minifyOptions": {
"enable": true,
"byteCodeHAR": true, // 启用 ByteCodeHAR 保护
"removeUnused": true,
"collapse": true
}
}
}
}
]
}2.3 ByteCodeHAR 模块配置
json5
// common/build-profile.json5
{
"module": {
"name": "common",
"type": "har",
"deviceTypes": ["phone", "tablet"],
"compileMode": "bytecode" // 关键:指定字节码编译模式
}
}2.4 构建产物对比
| 模块类型 | 正常 HAR | ByteCodeHAR |
|---|---|---|
| 产物内容 | .ets 源码 + .bc 字节码 | 仅 .bc 字节码 |
| 反编译难度 | 中(可还原为源码) | 高(仅能查看字节码) |
| 代码保护 | 低 | 高 |
| 适用场景 | 普通共享代码 | 核心业务代码 |
| 性能 | 标准 | 标准(编译一次,加载多次) |
3. 代码混淆深度配置
3.1 高级混淆配置
json5
{
"buildOptionSet": [
{
"name": "release",
"arkOptions": {
"obfuscation": {
"ruleOptions": {
"enable": true,
"includes": ["**/*.ets"],
"excludes": [
"**/model/*.ets",
"**/api/*.ets",
"**/config/*.ets",
"**/annotation/*.ets"
],
"proguardFiles": [
"obfuscation-rules.pro",
"third-party-rules.pro"
]
},
"minifyOptions": {
"enable": true,
"byteCodeHAR": true,
"removeUnused": true,
"collapse": true,
"stringOptimization": true,
"controlFlow": true,
"stringEncryption": true, // 字符串加密
"deadCodeElimination": true // 死代码消除
},
"resourceShrink": {
"enable": true,
"keepOriginal": false
}
}
}
}
]
}3.2 混淆规则详解
proguard
# ========================================
# 核心业务保护规则
# ========================================
# 保持入口类
-keep class com.example.myapp.entryability.** { *; }
# 保持数据模型(JSON 序列化)
-keep class com.example.myapp.model.** { *; }
-keep class com.example.myapp.dto.** { *; }
# 保持注解
-keep @interface com.example.myapp.annotation.** { *; }
# 混淆核心业务逻辑
-keepclassmembers class com.example.myapp.service.** {
public <methods>;
}
# 保持反射调用
-keepclassmembers class * {
@org.*** <methods>;
}
# 保持枚举
-keepclassmembers enum * {
public static **[] values();
public static ** valueOf(java.lang.String);
}4. 代码签名
4.1 签名流程
┌────────────┐ ┌──────────┐ ┌───────────┐ ┌──────────┐
│ 开发证书 │───▶│ 代码签名 │───▶│ 签名验证 │───▶│ 应用安装 │
│ (debug/release)│ │ (签名) │ │ (系统级) │ │ (安装) │
└────────────┘ └──────────┘ └───────────┘ └──────────┘4.2 签名配置
json5
// build-profile.json5
{
"app": {
"signingConfigs": [
{
"name": "release",
"type": "HarmonyOS",
"material": {
"certpath": "release.cer",
"storeFile": "release.p12",
"signAlg": "SHA256withECDSA",
"storePwd": "******",
"keyPwd": "******",
"keyAlias": "release_key"
}
}
]
}
}4.3 签名验证
typescript
// 检测应用是否被篡改
import { securityFramework } from '@kit.SecurityKit';
async function checkAppIntegrity(): Promise<boolean> {
try {
const integrity = await securityFramework.verifyAppSignature();
return integrity.isValid;
} catch (error) {
console.error('签名验证失败:', error);
return false;
}
}5. AntiTamper 防篡改检测
5.1 检测项
| 检测项 | 说明 |
|---|---|
| 签名验证 | 检查应用签名是否与预期一致 |
| 调试标志 | 检测应用是否被附加调试器 |
| 模拟器检测 | 检测是否在模拟器中运行 |
| Root/Jailbreak | 检测设备是否 Root |
| 代码注入 | 检测代码是否被注入 |
typescript
// anti-tamper 检测
import { securityFramework } from '@kit.SecurityKit';
export class AntiTamper {
/** 应用完整性检测 */
static async checkIntegrity(): Promise<boolean> {
const signatureCheck = await securityFramework.verifyAppSignature();
if (!signatureCheck.isValid) {
console.error('应用签名被篡改!');
return false;
}
// 调试检测
if (securityFramework.isDebuggerConnected()) {
console.error('检测到调试器!');
return false;
}
// Root 检测
if (securityFramework.isDeviceRooted()) {
console.warn('检测到 Root 设备');
}
// 模拟器检测
if (securityFramework.isEmulator()) {
console.warn('检测到模拟器运行');
}
return true;
}
}6. 敏感数据保护
6.1 安全存储
typescript
// 使用 deviceKeyStore 存储密钥
import { deviceKeyStore } from '@kit.SecurityKit';
class SecureStorage {
/** 加密存储 */
static async storeSecret(key: string, value: string): Promise<void> {
const encrypted = await deviceKeyStore.encrypt(value);
await deviceKeyStore.store(key, encrypted);
}
/** 加密读取 */
static async getSecret(key: string): Promise<string> {
const encrypted = await deviceKeyStore.retrieve(key);
return await deviceKeyStore.decrypt(encrypted);
}
}
// 使用场景
await SecureStorage.storeSecret('api_key', 'your-api-key-here');
const key = await SecureStorage.getSecret('api_key');6.2 加密方案
| 场景 | 方案 |
|---|---|
| API 密钥 | deviceKeyStore |
| 用户密码 | Argon2/Bcrypt |
| 数据加密 | AES-256-GCM |
| 数据签名 | ECDSA |
7. 面试高频考点
Q1: ByteCodeHAR 是什么?
回答要点:
- 字节码级 HAR 保护机制
- 编译为 .bc 字节码而非 .ets 源码
- 反编译难度更高
- 通过
compileMode: "bytecode"配置 - 保护核心业务逻辑不被源码级分析
Q2: 应用防篡改检测有哪些方式?
回答要点:
- 签名验证:检查应用签名
- 调试检测:检测是否被附加调试器
- Root/模拟器检测
- 代码注入检测
- 使用 securityFramework API
Q3: 代码保护的最佳实践?
回答要点:
- ByteCodeHAR 保护核心模块
- 混淆 + 字符串加密
- deviceKeyStore 存储密钥
- AntiTamper 检测
- 定期更新签名证书
8. Android 对比
| 概念 | Android | HarmonyOS |
|---|---|---|
| 源码保护 | ProGuard/R8 | ArkTS Obfuscator + ByteCodeHAR |
| 字节码保护 | Dex 字节码 | ArkTS ByteCode (.bc) |
| 签名 | APK Signature | AppGallery Signature |
| 防篡改 | SafetyNet | securityFramework |
| 密钥存储 | Keystore | deviceKeyStore |