端侧安全的整体图景

端侧安全不是某一个功能,而是一整条链:你申请的权限是否必要、拿到权限后用得是否克制、落盘的数据是否加密、网络传输是否可信,任何一环松懈,用户数据都可能泄露。鸿蒙的安全设计围绕"最小可用"展开——只给应用够用的权限,且使用过程对用户透明。

对开发者而言,最常打交道的是三块:权限申请、本地数据保护、网络通信。前两块做不好,审核很容易被拒;后一块做不好,即使审核通过,线上也会出事故。这篇按这个顺序展开。

安全不是加几道加密就完事,而是从"这个权限到底要不要"开始克制。能用系统能力替代私有数据采集的,就别申请权限。

权限模型:normal 与 system_grant

鸿蒙把权限分成几个等级。normal 类权限在安装时默认授予,不需要运行时弹窗,比如网络访问;而那些涉及隐私的敏感权限,属于 user_grant,必须在用到时动态申请,由用户明确授权。

两类权限的区别
  • normal风险低,安装即授予,配置在 module.json 里声明即可。
  • user_grant涉及隐私,必须运行时申请,且要先在配置里声明。
  • 声明先行任何权限都要先在配置文件里声明,运行时申请才有意义。
  • 最小化只申请功能真正需要的权限,多余权限会在审核中被要求说明。
鸿蒙应用安全示意:中央发光盾牌前方悬浮挂锁,周围环绕指纹轮廓、加密芯片方块与半透明数据叶片
安全的核心是克制:只申请够用的权限,拿到后按最小范围使用。

常见的 user_grant 权限包括定位、相机、麦克风、读取媒体文件、通讯录等。每次申请前都要想清楚:这个功能离开这项权限能不能做?能替代就别申请。

运行时权限申请流程

运行时申请的标准流程是:先检查是否已有权限,没有再发起请求,根据用户的选择决定后续路径。关键是不要一进应用就弹窗要权限,而是在用户触发相关功能的那一刻才申请。

import { abilityAccessCtrl } from '@kit.AbilityKit';
import { bundleManager } from '@kit.AbilityKit';

const atManager = abilityAccessCtrl.createAtManager();

async function ensureLocation(): Promise<boolean> {
  const ctx = getContext(this);
  const status = await atManager.checkAccessToken(
    bundleManager.getInfoSelf(ctx).accessTokenId,
    'ohos.permission.APPROXIMATELY_LOCATION'
  );
  if (status === abilityAccessCtrl.GrantStatus.PERMISSION_GRANTED) {
    return true;
  }
  // 弹系统授权框;用户拒绝后要给出引导,而非反复弹窗
  const res = await atManager.requestPermissionsFromUser(ctx,
    ['ohos.permission.APPROXIMATELY_LOCATION']);
  return res.authResults[0] === 0;
}

用户拒绝后正确的做法是:解释这项权限为什么必要,并引导用户去系统设置里手动开启,而不是在页面里反复弹系统框——那样只会加速卸载。

敏感权限的申请话术

用户看到系统授权框时往往一头雾水,所以在弹窗前,应该先用一段友好的说明告诉用户"我们要做什么、为什么需要这项权限、数据会怎么用"。这段说明是提升授权率和过审的关键。

  • 说清用途:用一句话把功能和权限对应起来,例如"用于显示附近的门店"。
  • 说清边界:说明数据是否上传、是否共享,让用户心里有数。
  • 给退路:允许用户拒绝后仍能用大部分功能,而不是一刀切除。
  • 不欺骗:说明文案要和实际行为一致,审核时会对照检查。

数据加密与密钥管理

拿到敏感数据后,落盘这一步要加密。鸿蒙提供了基于应用沙箱与密钥管理的能力,密钥由系统托管,开发者不需要自己把密钥写进代码。

把密钥硬编码进安装包,等于把家门钥匙贴在门上。任何能反编译 APK 的人都能取走它。

实践要点:敏感字段加密后再写库;日志里绝不打印明文;登出与卸载时清理对应数据。这和上一篇数据持久化里提到的加密落盘是同一套思路——存储负责"存得下",安全负责"存得安全"。

网络通信加固

网络这一层最基本的要求是全程 HTTPS,不在明文 HTTP 上传输任何敏感信息。进阶做法是证书固定(证书校验),防止中间人用伪造证书劫持流量。

另外,对服务端返回的数据永远不要完全信任:客户端校验、服务端也要校验,输入长度、类型、范围都要在边界处挡住。上传接口要加频率限制与文件类型白名单,否则很容易被刷量或塞入恶意文件。