在这里插入图片描述
在这里插入图片描述
在这里插入图片描述

一、前置思考

1.1 移动安全的历史困局

移动应用安全长期面临一个尴尬现实:大多数防护手段都是"应用自己防自己"。银行 App 在 Java 层做混淆,社交 App 在业务层做权限判断——但这些防护都建立在"操作系统可信"的前提下。一旦操作系统本身被攻破(root、刷机、Bootloader 解锁),应用层的所有防护都形同虚设。

我们回顾一下移动安全攻防的演变史,就能理解为什么"应用自保"这条路走不通:

阶段 时代 主要威胁 防护手段 结果
第一阶段 功能机时代 恶意短信、病毒软件 杀毒软件 杀软可被卸载,防护脆弱
第二阶段 早期智能机 Root 提权、ROM 篡改 应用内 root 检测 root 检测可被 Hook 绕过
第三阶段 大版本时代 Frida/Xposed 动态注入 混淆 + 加固 加固壳被脱壳工具逐一破解
第四阶段 万物互联时代 供应链攻击、深度伪造 系统级信任链 需要从硬件根部建立信任

结论很清晰:只要信任的起点还在"操作系统"或"应用自身",攻击者就有办法在信任链条之下做文章。正确的做法是把信任的起点下移到攻击者无法触及的硬件层。

1.2 鸿蒙星盾的回答

鸿蒙的星盾(Star Shield)安全架构想解决的根本问题是:把信任的起点从"操作系统"上移到"硬件"。它构建了一条从硬件可信根出发,逐级验证到应用层的完整信任链,任何一环被篡改,系统直接拒绝启动或运行。

星盾这个名字本身就说明了设计哲学:像盾牌一样,不是"挡一下",而是"形成完整的防护面"。它不是一个单点安全功能,而是一套贯穿芯片、内核、框架、应用四个层次的体系化安全方案。

1.3 本文的阅读路径

本文会从四个层次展开:

  1. 先讲清楚四层防护体系的整体架构与各层职责边界
  2. 深入安全启动链的每一级验证细节,理解"信任如何逐级传递"
  3. 剖析应用沙箱、权限模型、HUKS 等框架层安全机制的实现原理
  4. 给出可落地的代码示例、Demo 页面说明与避坑清单

二、核心原理

2.1 四层安全防护体系

┌─────────────────────────────────────────────┐
│            应用安全层 (App Security)          │
│  签名校验 · HUKS密钥 · 数据加密 · 组件导出控制 │
├─────────────────────────────────────────────┤
│            框架安全层 (Framework Security)    │
│  应用沙箱 · ATAM权限模型 · IPC鉴权 · 服务管控  │
├─────────────────────────────────────────────┤
│            内核安全层 (Kernel Security)       │
│  内核/用户态隔离 · SELinux MAC · 能力最小化    │
├─────────────────────────────────────────────┤
│            硬件可信根 (Hardware Root of Trust) │
│  TEE/SE芯片 · 安全启动ROM · 硬件加解密引擎     │
└─────────────────────────────────────────────┘

四层各有明确的职责,且互为依赖:

  • 硬件可信根:提供最底层的信任锚点。芯片内固化的 BootROM 公钥、TEE 可信执行环境、硬件加解密引擎,这些物理器件上的能力是攻击者无法通过软件手段篡改的。
  • 内核安全层:操作系统的最强防线。通过内核态/用户态隔离、SELinux 强制访问控制(MAC)、进程能力最小化,限制任何进程(包括被攻破的进程)能做的事情。
  • 框架安全层:开发者和应用直接交互的层。应用沙箱、ATAM(Access Token Access Manager)权限模型、IPC 鉴权、服务管控都在这一层,决定"应用能访问什么"。
  • 应用安全层:开发者的责任田。签名校验、HUKS 密钥管理、数据加密、组件导出控制,这部分做不好,前面三层再强也保护不了业务数据。

纵深防御(Defense in Depth)的关键思想:四层各自独立防护,单层被突破不影响整体。即使攻击者拿到了 root(突破了内核层),TEE 里的密钥依然拿不到;即使应用被重打包(突破了应用层),系统签名校验这一关也过不了。

2.2 安全启动链(Secure Boot Chain)

启动信任链是星盾架构的根基。我们把每一级的验证细节拆开来看:

BootROM(硬件固化,不可篡改)
   │ ① 验证 Bootloader 的签名(公钥烧录在芯片中,熔丝不可改写)
   ▼
Bootloader
   │ ② 验证系统镜像签名,拒绝未签名/被篡改内核
   ▼
内核启动(SELinux 策略加载、安全初始化、SMAP/SMEP 开启)
   │ ③ 验证 init 与关键系统服务的完整性
   ▼
init 进程(挂载沙箱文件系统、启动 servicemanager、加载权限策略)
   │ ④ 系统服务按权限策略启动,权限校验链路就绪
   ▼
系统服务(权限校验、沙箱策略生效、AMS/PMS 服务上线)
   │ ⑤ 应用安装时校验签名,运行时进入受限沙箱
   ▼
应用孵化(应用签名校验通过后才拉起,进入受限沙箱)

关键点:信任不是"声明"出来的,而是"逐级签名验证"出来的。每一级只信任上一级的签名验证结果,形成链式传递。任何一环被篡改,链条就断裂,系统直接拒绝启动。

三个值得深入的技术细节:

(1)信任锚点为什么放在芯片里?

BootROM 是芯片出厂时固化在硅片上的微码,其内含的公钥通过一次性可编程(OTP)熔丝烧录,物理上不可改写。这意味着攻击者即使拿到了设备硬件,也无法替换信任锚点——除非做芯片级的物理攻击(如探针、电子显微镜),而这种攻击成本极高,超出了绝大多数攻击者的能力范围。

(2)回滚保护(Anti-Rollback)

安全启动链还有一个重要特性:防止系统回滚到旧版本。因为旧版本可能含有已公开的漏洞,攻击者可以刷回旧系统利用漏洞提权。星盾架构通过"版本计数器 + 防回滚标记"实现:系统版本升级时计数器递增并写入防回滚存储区,降级安装时校验计数器,发现版本低于当前值直接拒绝。这让"刷回老版本找漏洞"的经典攻击路径被彻底封死。

(3)运行时完整性(Runtime Integrity)

启动时的签名验证只是静态信任,运行时还要防动态篡改。内核通过以下机制维护运行时完整性:

  • 只读内存页保护:关键代码段映射为只读,防止运行时改写
  • SELinux 策略热加载:策略文件经签名校验后才能加载
  • 内核模块签名校验:驱动模块必须带有效签名才能 insmod
  • 防篡改看门狗:关键服务崩溃或异常时触发安全处置流程

2.3 应用沙箱

每个应用默认运行在独立沙箱中:

资源 默认状态 访问条件
应用私有目录 可访问 无条件(files/cache/database)
其他应用目录 拒绝 无(除非系统级授权)
公共媒体库 拒绝 URI 临时授权 + 用户确认
网络 拒绝 INTERNET 权限
传感器/相机 拒绝 user_grant 权限
分布式文件 拒绝 同账号 + 权限校验

沙箱的实现涉及三个层次的技术:

(1)文件系统隔离

每个应用有独立的沙箱根目录 /data/storage/el2/base/haps/<module>/,内部再细分 files/cache/database/preferences/temp 子目录。文件系统的隔离不仅靠路径约定,更靠 SELinux 上下文:每个应用进程被分配独立的 SELinux 安全上下文,即使攻击者知道了其他应用的路径,由于 MAC 策略拒绝,也无法 open() 访问。

(2)进程隔离

每个应用以独立 UID 运行(支持多实例的应用可能有多个 UID),拥有独立的进程空间和句柄表。应用之间不能直接访问对方的进程地址空间,不能 ptrace 对方,不能读取对方的 /proc 信息。传统 Linux 的 ptrace 提权攻击路径在鸿蒙上被系统级禁用(普通应用之间不允许 ptrace)。

(3)能力隔离(Capability)

进程携带最小能力集,只授予其完成任务所需的能力。沙箱内应用默认只有基本能力,网络、传感器、外设等能力都需要显式授权。即使应用被攻破,其能力集也限制了攻击者的横向移动空间。

2.4 权限模型(ATAM)

沙箱解决"能不能碰",权限模型解决"有没有资格碰"。鸿蒙的权限模型基于 accessToken 令牌:

  • system_grant 权限:安装时静默授予,如 INTERNET。这类权限无用户感知,但系统依然记录在案。
  • user_grant 权限:运行时动态申请,弹窗确认,如 CAMERA、LOCATION。用户可随时在设置中撤销。
  • system_basic 权限:系统级权限,仅系统应用可申请。
  • restricted 权限:受限权限,需要特权申请流程。

权限校验走 AtManager 链路:应用调用敏感 API → 系统解析 tokenId → 查询权限表 → 校验时效/撤销状态 → 返回授权结果。每次使用前实时校验,不依赖应用缓存,这是与旧系统最大的差异——应用无法通过缓存授权状态绕过撤销。

2.5 HUKS 密钥体系

HUKS(HarmonyOS Universal KeyStore)是密钥管理的统一出口:

  • 密钥不出硬件:密钥在 TEE/SE 内生成、使用,应用只拿到句柄(alias)
  • 用途绑定:生成时声明用途(加密/签名/派生),防止密钥被滥用
  • 访问控制:可绑定指纹/口令,解锁后才能使用
  • 密钥轮换:支持弱算法密钥识别与轮换

重要区别:HUKS 密钥与应用的安装绑定。卸载重装后,HUKS 密钥随之删除(除非开启云备份迁移),这意味着加密数据在卸载后无法解密——这是很多团队忽略的坑,需要在产品层面设计备份策略。

2.6 可信根认证

// 应用侧可通过系统接口感知安全能力(示意)
import { bundleManager } from '@kit.AbilityKit';

class StarShieldInspector {
  // 检查设备是否满足安全要求
  static checkDeviceSecurity(): boolean {
    const bundleInfo = bundleManager.getBundleInfoForSelfSync(
      bundleManager.BundleFlag.GET_BUNDLE_INFO_DEFAULT
    );
    // 签名指纹校验(防重打包)
    const fingerprint: string = bundleInfo.signatureInfo.fingerprint;
    return fingerprint !== '00000000000000000000000000000000';
  }
}

注意:这只是一个"感知"示例。正确做法不是应用自己实现安全判断,而是调用系统提供的安全能力接口,让系统告诉你"当前环境是否可信、密钥是否可用、生物认证是否通过"。

三、典型攻击场景还原

理解安全架构最好的方式,是站在攻击者视角走一遍攻击链,看每一条路为什么走不通。

3.1 场景一:重打包攻击

攻击者操作:
1. 下载正版 App → 解包
2. 插入恶意代码(盗号逻辑/广告注入)
3. 重新签名(自签名或盗用证书)
4. 诱导用户安装"高仿版"

被拦截的环节:
① 系统安装时签名校验:自签名证书与官方不符 → 拒绝安装
② 若强制安装成功:应用内完整性校验检测到资源哈希变化 → 拒绝运行
③ 运行时签名指纹校验:signatureInfo.fingerprint 与白名单不符 → 阻断敏感操作

3.2 场景二:Root 提权

攻击者操作:
1. 解锁 Bootloader → 刷入 Magisk
2. 获取 root 权限 → 读取应用私有数据

被拦截的环节:
① Bootloader 解锁触发安全状态标记,设备进入"已解锁"状态
② 敏感应用的密钥存于 TEE,root 进程无法访问 TEE 内存
③ 应用数据即使被读到也是密文(HUKS 密钥不在普通文件系统)
④ 应用可通过系统接口感知设备安全状态,决定是否降级敏感功能

3.3 场景三:中间人攻击

攻击者操作:
1. 伪造 Wi-Fi 热点
2. 下发自签名证书
3. 尝试解密 HTTPS 流量

被拦截的环节:
① 证书链验证:自签名证书不在信任库 → 握手失败
② SSL Pinning:应用内置服务器指纹,指纹不符 → 连接中断
③ 即便流量被解密,请求签名校验(防重放)也会拒绝伪造请求

四、实战落地

对应 Demo 页面:entry/src/main/ets/pages/SecurityArchitectureDemo.ets

Demo 包含三个 Tab:

  1. 分层架构:展示四层防护体系,支持一键"四层自检",统计各层可信状态
  2. 安全启动链:逐步动画演示 BootROM→Bootloader→内核→init→系统服务→应用孵化的逐级验证过程
  3. 应用沙箱:列出私有目录/公共媒体库/分布式文件的隔离策略,可切换演示隔离状态
// Demo 核心逻辑:安全启动链逐级点亮
private startBootVerification(): void {
  // 6 个阶段依次验证,每阶段 400ms 间隔
  for (let i: number = 0; i < this.bootStages.length; i++) {
    const idx: number = i;
    setTimeout(() => {
      this.bootStages[idx].status = 'pass';
      if (idx === this.bootStages.length - 1) {
        this.trustRootVerified = true;
      }
    }, 400 * (idx + 1));
  }
}

4.1 应用侧落地的四件事

作为应用开发者,在星盾架构下有四件必须做好的事:

第一件:签名完整性校验

在启动时(或敏感操作前)比对 signatureInfo.fingerprint 与白名单。校验逻辑建议放 native 层,避免被 Hook 绕过;且比对的是"包名 + 签名哈希"而非类名,防止混淆破坏自校验。

第二件:敏感数据全加密落盘

数据库、偏好、缓存中的敏感字段一律密文存储,密钥走 HUKS。明文落盘的敏感数据是数据泄露事故的最大来源。

第三件:权限声明精确化

只声明业务真正需要的权限。user_grant 权限必须在 module.json5 中声明 reasonusedScene,否则编译报错;权限申请时机跟随业务场景,不提前、不批量。

第四件:正确使用系统安全能力

能走系统能力的不要自己造轮子:文件隔离走沙箱、密钥管理走 HUKS、生物认证走系统接口、跨应用分享走 URI 临时授权。自造的"安全轮子"往往比系统能力弱得多。

4.2 与 iOS/Android 的安全架构对比

维度 鸿蒙星盾 iOS Android
信任起点 芯片 BootROM + TEE 芯片 Secure Enclave 芯片 + 可选 TEE
应用隔离 沙箱 + SELinux MAC 沙箱 + Code Sign 沙箱 + SELinux
权限模型 accessToken 令牌 + 分级 运行时权限 + 隐私面板 运行时权限
密钥管理 HUKS(TEE 内) Keychain(SE 内) Keystore(TEE 内)
跨设备安全 分布式软总线 + 设备认证 AirDrop + Handoff 无系统级方案

从表中可以看到,鸿蒙在"跨设备安全"上是独一份的——这与 iOS/Android 的单设备安全模型有本质区别,也是分布式场景下的核心差异化能力。

五、避坑速查

现象 原因 解决
混淆后签名校验失败 升级后无法启动 混淆改变了类结构导致自校验误判 校验逻辑放 native 层,且使用包名+签名哈希而非类名
沙箱路径硬编码 换机型路径失效 沙箱根路径随用户/版本变化 context.filesDir 等系统接口获取,不写死
误认为沙箱可关闭 想访问公共目录失败 沙箱不可关闭,只能授权 走 MediaLibrary/文件选择器 + URI 授权
依赖 root 检测兜底 普通用户也被误判 root 检测过严 root 检测只作为风险提示,不做功能阻断
忽略签名指纹校验 重打包后数据泄露 未校验签名指纹 安装/启动时比对 signatureInfo.fingerprint
密钥明文存 SharedPreferences 备份文件泄露密钥 贪图方便不入 HUKS 密钥一律 HUKS,Preferences 只存非敏感数据
组件默认导出 应用被任意拉起 未显式设置 exported:false 无跨应用需求一律 exported:false
升级签名不一致 提示无法覆盖安装 换了签名证书 升级必须沿用同一证书链
卸载重装数据丢失 加密数据无法解密 HUKS 密钥随卸载删除 设计云备份/迁移策略或提示用户
忽略防回滚 设备被刷回有漏洞版本 未开启防回滚标记 系统版本升级走标准防回滚流程

六、总结

星盾安全架构的核心思想可以概括为三句话:

  1. 信任链从硬件出发:BootROM 固化公钥,逐级签名验证,从源头杜绝"系统被替换"
  2. 沙箱兜底,权限细化:应用默认零权限,一切资源访问都需显式授权
  3. 纵深防御:硬件→内核→框架→应用四层各自独立防护,单层被突破不影响整体

对开发者而言,理解星盾架构的意义在于:不要在应用层自己造安全轮子(自校验、自加密),而是充分信任系统提供的沙箱、权限、HUKS 能力,把精力放在正确的权限声明、合理的加密策略和签名完整性校验上。

最后给出一个落地检查清单:

  • 应用签名指纹校验已实现(native 层)
  • 所有敏感数据密文落盘,密钥走 HUKS
  • module.json5 权限声明完整(含 reason/usedScene)
  • 组件导出已收敛(exported:false 默认)
  • 网络层已全流量 HTTPS + 证书校验
  • 沙箱路径全部通过 context 接口获取
  • 卸载重装场景的密钥/数据策略已设计
Logo

作为“人工智能6S店”的官方数字引擎,为AI开发者与企业提供一个覆盖软硬件全栈、一站式门户。

更多推荐