写点什么

跨平台应用开发进阶 (五十二):安全合规之 Android APP 完整性校验机制探究

  • 2023-04-21
    上海
  • 本文字数:2020 字

    阅读完需:约 7 分钟

跨平台应用开发进阶(五十二):安全合规之Android APP完整性校验机制探究

一、前言

Android 系统开放免费,开发者和用户都趋之若鹜。用户已经习惯了 Android 应用的这种免费午餐,但背后却隐藏着巨大的安全隐患。


在对 APP 进行渗透测试时,要求提供 APP 是否具备完整性校验机制,防止被重签名和二次打包(采用混淆、验证签名、服务器端验证等技术防范二次打包等;)


注⚠️:APK 的唯一标识取决于包名和签名。

二、二次打包

什么是二次打包?二次打包流程:破解者需要对 APK 文件做反编译分析,反编译为 smali 代码,并对某些关键函数或者资源进行修改,再次编译为 apk 文件并重签名。


二次打包会篡改签名,通过签名前后的变化可以检测是否被二次打包。


二次打包主要用到 3 个工具,apktooldex2jarjd-gui


  • apktool:反编译利器;

  • dex2jar:将 dex 文件反编译成 jar 文件(java 代码)工具,用于解读代码;

  • jd-gui:打开 jar 文件工具;

三、解决措施

3.1 混淆

可通过在 IDE 配置混淆规则。


uni-app 实现的话,支持js/nvue文件原生混淆加密,考虑到加解密的性能损耗,所以应选取项目中比较重要的js/nvue文件。


注⚠️:uni-app的 js 运行在独立的jscore中,而不是webview中,所以不受 iOS 平台WKWebview不支持原生混淆的限制。 uni-app的 vue 页面中的 js,是整体编译到一个大 js 文件中的,它经过编译,已经不再是 vue 源码了,但还不是乱码。对这个统一的大文件进行混淆会有影响性能。 所以uni-app只支持独立混淆nvue/js文件。


HBuilderX2.6.3+版本开始,uni-app项目使用 v3 编译器支持对 vue 页面中引用的 js 文件进行原生混淆


manifest.json文件中添加要混淆的 js 文件列表:


"app-plus": {     "confusion": {          "description": "原生混淆",          "resources": {              "common/test.js" : {}        }       },      // ...  }
复制代码


在 vue 文件中引用混淆的 js 文件:


import test from '../common/test.js';//test.join();  //调用引用js中的方法
复制代码


提交云端打包配置好原生混淆的文件列表后,需要提交云端打包,注意在 App 云端打包对话框中需要勾选“对配置的 js 文件进行原生混淆



注⚠️:为保证加密数据的安全性,HBuilder 加密算法和 key 不对外公开,因此离线打包无法支持原生混淆。 熟悉原生的开发者可将敏感信息存放于原生代码中,再与 js 进行交互。


对安全性要求较高的开发者,除了对前端 js 进行加密外,还应该对整个 apk 再进行一次加固。市面上很多加固服务可以选择,比如腾讯云乐固、360 加固、爱加密等。

3.2 签名验证

3.2.1 什么是 apk 签名

签名是摘要与非对称密钥加密相相结合的产物,摘要就像内容的一个指纹信息,一旦内容被篡改,摘要就会改变,签名是摘要的加密结果,摘要改变,签名也会失效。Android APK 签名也是这个道理,如果 APK 签名跟内容对应不起来,Android 系统就认为 APK 内容被篡改了,从而拒绝安装,以保证系统的安全性。


应用程序的作者使用自己的私钥签名 APK 文件,并将签名与公钥一起发布到 APK 中,这个过程称之为签名。当应用程序被安装时,用发布的公钥去解析签名,并与文件的 hash 进行比对,这个过程叫验签

3.2.2 为什么需要签名

在消息通信时,必须至少解决两个问题:一是确保消息来源的真实性,二是确保消息不会被第三方篡改。


签名机制主要有两种用途:


  • 使用特殊的 key 签名可以获取到一些不同的权限;

  • 验证数据保证不被篡改,防止应用被恶意的第三方覆盖;


防止被二次打包的一种方法是进行签名验证。Android 安全的基石之一是所有的 app 都必须经过数字签名。APP 二次打包时需要经过反编译——>修改源码——>二次打包——>二次签名,所以攻击者要对开发者的 apk 进行代码恶意篡改,重新打包时必须重新进行数字签名,这样就破坏掉了原有的数字签名。所以攻击者肯定会用另一个秘钥进行重新签名,所以可以将签名信息事先存储至服务端,如果在 app 中启动时对签名进行校验,就能识别 app 是否被重新二次打包过,识别出被二次打包后对用户进行提示,防止用户关键信息泄露或被攻击。


注⚠️:可记录证书指纹中 SHA1 码,将此 SHA1 码存储到服务端中,作为 app 是否被重新签名的验证凭据。


此方法只能简单校验 apk 是否被篡改过,而且证书指纹直接写在 java 代码中也容易被反编译看到破解,甚至修改判断逻辑。更好一点的改进方式是将证书指纹及判断逻辑都用 ndk 开发,放到 so 库里面。

3.3 服务端验证

3.4 核文件完整性校验

二次打包前后 apk 关键文件 hash 值比较,判断是否被修改。


可以将 app 中重要文件的 hash 值存储到服务器,在 app 启动时计算重要文件的 hash 值与服务器进行对比。

3.5 APK 加固+核心方法保护

应用第三方专业 APP 安全防护加固平台可实现 APK 加固,免费版的加固层级较浅,仅针对个人开发者,企业级 APP 建议升级至企业版加固方案。


加固后smali文件与未加固的变化很大,极大增加了反编译代码阅读难度。而且再用apktool进行打包时会报错,不能成功进行打包。真正起到了防止二次打包的作用。通过签名校验保护,能有效避免应用被二次打包。

四、拓展阅读

发布于: 刚刚阅读数: 5
用户头像

No Silver Bullet 2021-07-09 加入

岂曰无衣 与子同袍

评论

发布
暂无评论
跨平台应用开发进阶(五十二):安全合规之Android APP完整性校验机制探究_android_No Silver Bullet_InfoQ写作社区