news 2026/9/19 22:52:55

uni-app 客户端安全 API 实战指南:签名校验、模拟器/越狱检测与代理识别

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
uni-app 客户端安全 API 实战指南:签名校验、模拟器/越狱检测与代理识别
  • 示例工程
  • 前端
  • 移动开发
  • 跨平台

【免费下载链接】uni-app

A cross-platform framework using Vue.js

项目地址:https://gitcode.com/gh_mirrors/un/uni-app
点击查看免费下载

本篇技术指南围绕 uni-app 与 uni-app x 提供的客户端安全 API展开,系统讲解如何通过plus.navigator.getSignatureplus.navigator.isSimulatorplus.networkinfo.isSetProxyplus.navigator.isRoot等接口识别应用是否被重签名、运行在模拟器/越狱环境、网络是否被代理劫持,以及设备是否开启 USB 调试。读完本文,你将掌握一套可直接落地的客户端风控方案:既能在 App 启动时拦截异常运行环境,也能把安全状态上报业务服务器进行登录风控,并配合原生混淆加密与加固防止校验代码被篡改。

一、为什么客户端需要安全 API

uni-app 与 5+ App 提供了一批用于获取客户端安全相关信息的 API。这些信息的价值在于:App 的安装包可以被解压、被反编译、被二次打包,运行环境也不受开发者控制——模拟器、越狱/root 设备、代理网络都可能成为黑产攻击的入口。

| API | 能力 | uni-app 支持 | uni-app x 支持 | | :- | :- | :-: | :-: | |plus.navigator.getSignature| 获取应用签名标识,判断是否被重新签名 | ✔ | 通过uni.getAppBaseInfo().signature| |plus.navigator.isSimulator| 判断是否运行在模拟器 | ✔ | 通过uni.getDeviceInfo().isSimulator/uni.isSimulator()| |plus.networkinfo.isSetProxy| 判断网络环境是否设置代理 | ✔ | 暂不支持 | |plus.navigator.isRoot| 判断设备是否被 root/越狱(仅 iOS) | ✔ | 通过uni.getDeviceInfo().isRoot| |plus.navigator.isUSBDebugging| 判断是否开启 USB 调试(仅 Android) | 不支持 | 通过uni.getDeviceInfo().isUSBDebugging|

注意:官方更推荐使用 uni 云端一体安全网络方案,接入安全网络后将无需再使用本章节提供的 API。对于未接入安全网络的项目,本文的 API 校验仍是有效的兜底手段。

二、应用签名标识校验:拦截二次打包仿冒

2.1 为什么签名校验如此关键

签名证书是对 App 开发者身份的唯一标识。如果程序未对签名证书进行校验,App 被反编译后可能被二次打包,使用其它签名证书重新签名。若重新签名的 App 可以正常启动,则可能导致:

  • App 被仿冒盗版,影响合法收入;
  • 被添加钓鱼代码、病毒代码、恶意代码;
  • 用户敏感信息泄露或遭受恶意攻击。

因此,在应用启动时校验签名,能第一时间识别出"非官方签名"的安装包。

2.2 uni-app 项目:使用 plus.navigator.getSignature

plus.navigator.getSignature用于获取应用签名标识。在 uni-app 项目中,建议在App.vue的应用生命周期onLaunch中进行校验,示例代码如下:

onLaunch: function(inf) { console.log('App Launch'); // #ifdef APP-PLUS // 签名证书检验 var platform = uni.getSystemInfoSync().platform; var sign = plus.navigator.getSignature(); if('android'==platform){ //Android平台 var sha1 = 'baad093a82829fb432a7b28cb4ccf0e9f37dae58'; //修改为自己应用签名证书SHA-1值,是全小写并且中间不包含":"符号 if(sha1!=sign){ //证书不对时退出应用 plus.runtime.quit(); } }else{ //iOS平台 var md5 = 'a2e629f0ea915b4ed11e296a059c9a12'; //修改为自己应用Apple Bunld ID(AppID)的md5值 if(md5!=sign){ //不进入应用或循环弹出提示框 console.log('应用被破坏,无法正常运行!'); uni.showModal({ title:'错误', content: '应用被破坏,无法正常运行!', }); } } // #endif }

关键参数说明:

  • Android 平台sign返回的是应用签名证书的 SHA-1 值,必须全小写且中间不包含:符号。可通过keytool -list -v -keystore 你的签名文件.keystore查看证书指纹后转小写并去掉冒号填入。
  • iOS 平台sign返回的是应用签名证书中绑定的 Bundle ID(Apple ID)的md5 值,同样为全小写。可在打包前用echo -n "你的BundleID" | md5之类的方式计算后填入。
  • 退出策略:Android 上签名不符时直接plus.runtime.quit()退出;iOS 上可弹窗提示后退出或持续拦截,开发者可根据产品策略调整。

2.3 uni-app x 项目:使用 uni.getAppBaseInfo().signature

uni-app x 项目不支持 plus API,需使用 uni.getAppBaseInfo 返回值中的signature属性。其取值规则与 plus 版本一致:

  • Android:应用签名证书的 SHA1 值(全部为小写,中间不包含:);
  • iOS:应用签名证书中绑定的 Bundle ID(AppleID)的 md5 值(全部为小写)。

从仓库源码看,Android 侧的实现位于 AppBaseInfoDeviceUtil.uts:通过PackageManager.GET_SIGNATURES读取安装包签名,用MessageDigest.getInstance("SHA1")计算摘要,再将每个字节转换为不带冒号的十六进制小写字符串,与文档规定的取值格式完全对应。这意味着你预埋的 SHA-1 白名单必须与框架输出格式一致(全小写、无冒号)。

2.4 防止校验代码被篡改

签名校验代码本身位于 js 中,存在被反编译篡改的风险。官方建议:

  • 将签名校验代码放到独立 js 文件中
  • 配置 js/nvue 文件原生混淆加密;
  • 或使用 apk 加固处理。

三、模拟器检测:isSimulator

3.1 模拟器环境的危害

plus.navigator.isSimulator用于判断当前应用是否运行在模拟器中。iOS 系统由于苹果限制正式打包后不能在模拟器上运行,一般不存在此问题;但 Android 系统是开源的、底层代码全部公开,市面上存在大量 Android 模拟器,问题比较严重:

  • 模拟器通常运行在 PC 上,可利用自动化工具自动操作 App(批量注册、刷单、薅羊毛);
  • 模拟器是虚拟操作系统,可能破坏原生系统的安全性,导致用户敏感信息泄露。

3.2 uni-app 项目:在 onLaunch 中拦截

onLaunch: function(inf) { console.log('App Launch'); // #ifdef APP-PLUS // 模拟器检验 if(plus.navigator.isSimulator()){ //弹出提示框 uni.showModal({ title:'错误', content: '应用被不能运行到模拟器!', complete: ()=>{ plus.runtime.quit(); } }); } // #endif }

3.3 uni-app x 项目与模拟器检测的底层原理

uni-app x 项目可通过 uni.getDeviceInfo 返回值中的isSimulator属性获取。需要注意:受隐私合规政策影响,从 4.51 版本起uni.getDeviceInfo中的isSimulator不再采集传感器信息,准确度会下降;如需更准确的判断,应使用独立的 uni.isSimulator API(Android 4.51+、iOS 4.51+),它会采集传感器信息以更准确地识别模拟器,但在 Android 应用商店上线时必须在隐私协议中声明,并确保在用户同意隐私协议后再调用。iOS 平台暂请继续使用uni.getDeviceInfo

从源码看,Android 侧的模拟器检测逻辑集中在 EmulatorCheckUtil.uts,采用"多维特征 + 嫌疑值累计"的机制:

  • 硬件名称ro.hardware):命中ttvm(天天模拟器)、nox(夜神)、cancro(网易 MUMU)、intel(逍遥)、vbox/vbox86(腾讯手游助手)、android_x86(雷电)等即判定为模拟器;
  • 已知包名:检测com.bluestacks.home(蓝叠)、com.microvirt.guide(逍遥)等模拟器残留文件;
  • 构建渠道ro.build.flavor):包含vboxsdk_gphone判定为模拟器;
  • 设备型号 / 制造商 / 主板 / 平台 / 基带:如google_sdkemulatorgenymotionneteasegoldfish等特征值;
  • 硬件能力:检测是否支持闪光灯、蓝牙;
  • 传感器数量与光线传感器:传感器数量过少或缺少光线传感器会增加嫌疑值;
  • 最终嫌疑值大于 3 即判定为模拟器,同时每个维度都有"可能是模拟器/可能是真机"的中间状态,避免误杀。

3.4 业务侧的风控应用

实际项目中不必直接禁止运行,更推荐将模拟器状态提交业务服务器进行判断,例如:

  • 模拟器环境不允许登录;
  • 多次尝试在模拟器登录可临时封号;
  • 由人工客服联系用户核实。

具体策略可根据业务情况进行调整。

四、网络代理检测:isSetProxy

4.1 代理网络的威胁

plus.networkinfo.isSetProxy用于判断当前应用网络环境是否设置代理。设置代理后,所有网络传输的数据都会经过代理服务器,意味着:

  • 代理服务器可能看到所有传入内容,导致用户敏感信息泄露;
  • 业务服务器可能被恶意攻击(抓包分析接口、重放攻击等)。

当然也存在例外:某些企业内部网络为保证安全,访问公网时可能必须设置代理。开发者需要权衡这种需求,决定是否限制应用正常运行。

4.2 在登录时上报代理状态

可以在用户登录时提交当前网络环境是否使用代理,示例代码如下:

function login() { //... //获取网络代理状态 var isProxy = plus.networkinfo.isSetProxy(); if(isProxy){ console.log("当前网络环境设置了代理!"); } //将使用代理状态提交给业务服务器 //... }

4.3 平台支持情况

  • uni-app 项目可通过plus.networkinfo.isSetProxy获取;
  • uni-app x 项目暂不支持该能力,开发者需通过服务端风控等手段做替代判断。

五、Root/越狱检测:isRoot

5.1 越狱环境的危害

plus.navigator.isRoot用于判断当前应用运行的设备是否被 root 破解。注意:仅 iOS 平台支持,Android 平台暂不支持(Android 侧可参考下一节的 uni-app x 方案)。

root 破解(也叫越狱)是利用 iOS 系统漏洞破解系统安全机制,让任何应用获得系统级权限,从而对系统进行更灵活的自定义修改(修改字体、修改主题、使用插件等)。iOS 设计了沙盒机制,限制应用只能使用自身的数据;root 破解后,应用可以读取、修改其它任何应用的数据,可能导致:

  • 用户敏感信息泄露;
  • 其它应用的数据或代码被篡改,正常 App 遭到恶意攻击。

5.2 在应用启动时检测

建议在应用启动时判断,若运行在 root 破解环境则提示用户无法正常使用。uni-app 项目可以在App.vue的应用生命周期onLaunch中进行校验:

onLaunch: function(inf) { console.log('App Launch'); // #ifdef APP-PLUS //ROOT检验 if(plus.navigator.isRoot()){ //弹出提示框 uni.showModal({ title:'错误', content: '应用被不能运行到越狱或ROOT环境!', complete: ()=>{ //循环弹出提示框或死循环引起应用退出 } }); } // #endif }

5.3 uni-app x 项目

uni-app x 项目可通过 uni.getDeviceInfo 返回值中的isRoot属性获取,其兼容性为 Android 3.9+、iOS 4.11+。其中 iOS 表示是否越狱。从源码看,iOS 侧实现直接封装了UTSiOS.isRoot()(见 DeviceUtil.uts),Android 侧则通过DeviceUtil.hasRootPrivilege()判断(见 index.uts)。

六、USB 调试检测:isUSBDebugging

该能力用于判断当前应用运行的设备是否开启 USB 调试,仅 Android 平台支持

  • uni-app 项目不支持获取此状态
  • uni-app x 项目可通过 uni.getDeviceInfo 返回值中的isUSBDebugging属性获取,其实现通过检测 ADB 监听状态完成(DeviceUtil.listeningForADB(),见 index.uts)。

开启 USB 调试的设备更容易被 ADB 等调试工具接管,可结合代理检测、模拟器检测一起构成登录风控的多维信号。

七、防止校验代码被篡改:混淆加密与加固

上述安全校验都依赖前端 js 代码,而 App 安装包都可以解压,前端资源通常明文存放在安装包中。为防止校验代码被解包后篡改绕过,DCloud 提供了 App 端 js/nvue 文件的原生混淆能力,详见 js/nvue 文件原生混淆加密,要点如下:

  1. uni-app 项目:在manifest.jsonapp-plus.confusion.resources节点下配置要混淆的 nvue/js 文件列表,键名为文件相对路径,值为空对象:
"app-plus": { "confusion": { "description": "原生混淆", "resources": { "common/test.js" : {} } }, // ... }
  1. 在 vue 文件中通过import引用被混淆的 js;HBuilderX2.6.3+ 版本 v3 编译器支持 vue 页面引用的独立 js 文件原生混淆,HBuilderX2.3.4+ 版本支持 nvue 文件原生混淆。
  2. 提交云端打包时,必须在 App 云端打包对话框中勾选"对配置的 js 文件进行原生混淆"。由于加密算法和 key 不对外公开,离线打包无法支持原生混淆加密,标准基座/自定义基座真机运行也不支持(仅正式云打包支持);制作 wgt 包同样不支持(HBuilderX3.1.0+ 版本后支持)。
  3. 没有绝对的安全:非常重要的信息应保存在服务器而非前端;运行期解密会影响性能,不建议全包混淆,只挑选需要保护的个别文件即可。
  4. 对安全性要求较高的开发者,除前端 js 加密外,还应对整个 apk 再做一次加固,可参考 uni 安全加固,能有效提升应用整体安全性。

八、综合实践与注意事项

8.1 组合使用建议

将本文的 API 按场景组合,可形成一套完整的客户端风控链路:

  1. 启动阶段onLaunch):校验应用签名(防二次打包)+ 检测模拟器 + 检测越狱/root(iOS);
  2. 登录阶段:上报网络代理状态 + 模拟器状态 + USB 调试状态到业务服务器;
  3. 服务端策略:根据上报的安全信号决定是否放行、二次验证、临时封号或人工核实。

8.2 关键注意事项

  • uni-app x 与 plus API 的差异:uni-app x 项目不支持plus.xxx系列 API,统一改用uni.getAppBaseInfo().signatureuni.getDeviceInfo().isRoot / isSimulator / isUSBDebugging,代理检测(isSetProxy)在 uni-app x 中暂不可用。
  • 平台限制plus.navigator.isRoot仅 iOS;USB 调试检测仅 Android;这些限制在使用前必须明确。
  • 隐私合规:涉及传感器信息采集的uni.isSimulator必须在隐私协议中声明,并在用户同意后再调用;uni.getDeviceInfo支持filter参数按需获取字段,例如只取品牌时不传isSimulator可避免触发传感器采集(uni.getDeviceInfo({filter:["brand"]}))。
  • 代码保护:所有安全校验代码都应放入独立 js 并配置原生混淆加密,配合 apk 加固,避免被反编译篡改绕过。
  • 平台能力边界:原生混淆仅限正式云打包生效,且部分老版本编译器存在限制,接入前请核对 HBuilderX 版本要求。

以上所有 API 的返回值与行为,均可结合 uni.getAppBaseInfo、uni.getDeviceInfo、uni.isSimulator 文档以及仓库中的 uni-getAppBaseInfo、uni-getDeviceInfo 模块源码逐一验证。

  • 示例工程
  • 前端
  • 移动开发
  • 跨平台

【免费下载链接】uni-app

A cross-platform framework using Vue.js

项目地址:https://gitcode.com/gh_mirrors/un/uni-app
点击查看免费下载

相关推荐

创作声明:本文部分内容由AI辅助生成(AIGC),仅供参考

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/19 22:52:42

操作系统试题结构化处理与自动化校验技术

简介:本资源是面向计算机专业本科生及备考操作系统的考生整理的《计算机操作系统(第四版)》配套习题集与详解,聚焦期末考试复习与核心概念巩固。内容覆盖进程管理、内存管理(分页/分段/虚拟存储)、文件系统…

作者头像 李华
网站建设 2026/9/19 22:48:35

Windows更新文件清理指南:安全释放C盘空间

1. 项目概述:为什么你总在“删更新文件”这件事上反复折腾?Windows更新文件删除,不是个技术问题,而是一个系统与用户之间持续博弈的日常现场。我做IT支持和系统运维十多年,几乎每天都会遇到三类人:一类是C盘…

作者头像 李华
网站建设 2026/9/19 22:42:34

2026年PyCharm安装配置全攻略:从下载到跑通第一个项目

1. 为什么2026年还要认真装一次PyCharm很多人看到"安装教程"四个字就划走了,觉得装个软件有什么好讲的,下一步下一步不就完了。但我这些年帮人看环境问题,十次里有七次出在第一步——装的时候随手点,用的时候到处报错。…

作者头像 李华
网站建设 2026/9/19 22:41:38

Branch节点深度解析:读取节点图分支逻辑与性能优化实战

在节点式开发环境里待久了,你会发现一个特别有意思的现象:Branch节点是被用得最多、但最被低估的节点之一。很多人拖一个Branch节点出来,接上布尔值,两条输出一接,就认为大功告成。但等到项目复杂起来,分支…

作者头像 李华