`
shuai1234
  • 浏览: 926524 次
  • 性别: Icon_minigender_1
  • 来自: 山西
社区版块
存档分类
最新评论

Android客户端代码保护技术-完整性校验

 
阅读更多

  由于Android系统固有的缺陷、Android应用分发渠道管理机制等问题,导致Android客户端程序很容易被反编译篡改/二次打包,经任意签名后可在各个渠道或论坛中发布,这不仅损害了开发者的知识产权,更可能威胁到用户的敏感信息及财产安全,因此客户端程序自身的安全性尤为重要,本文以客户端完整校验为主题,提供几种Android客户端完整性校验的实现思路,供广大开发者参考。

思路1:对classes.dex文件完整性校验

       Android工程代码中的所有java代码经编译和优化最终生成Dalvik虚拟机可执行的DEX文件,DEX文件最终会打包在APK文件中,针对APK代码的篡改攻击就是针对该文件,如通常使用apktool反编译APK文件,修改smali代码。APK包中的DEX文件如下图所示:

       因此,我们可以设计编写校验代码,实现在应用程序启动时计算所程序安装包中的classes.dex文件的哈希值(可通过CRC32、MD5等摘要算法计算得到),然后与预先计算的dex文件的哈希值(该值可存储在代码或配置文件中、也可与服务器通信交互获取)进行比较,以此验证代码文件是否被篡改。

       通过检查classes.dex文件的CRC32摘要值来判断文件是否被篡改的java实现代码如下所示:

[java] view plain copy
 
  1. /** 
  2.  * 通过检查classes.dex文件的CRC32摘要值来判断文件是否被篡改 
  3.  * 
  4.  * @param orginalCRC 原始classes.dex文件的CRC值 
  5.  */  
  6. public static void apkVerifyWithCRC(Context context, String orginalCRC) {  
  7.     String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径  
  8.     try {  
  9.         ZipFile zipFile = new ZipFile(apkPath);  
  10.         ZipEntry dexEntry = zipFile.getEntry("classes.dex"); // 读取ZIP包中的classes.dex文件  
  11.         String dexCRC = String.valueOf(dexEntry.getCrc()); // 得到classes.dex文件的CRC值  
  12.         if (!dexCRC.equals(orginalCRC)) { // 将得到的CRC值与原始的CRC值进行比较校验  
  13.             Process.killProcess(Process.myPid()); // 验证失败则退出程序  
  14.         }  
  15.     } catch (IOException e) {  
  16.         e.printStackTrace();  
  17.     }  
  18. }  

 

思路2:对apk包做完整性校验

       如果对apk包进行篡改,必会影响apk包的完整性校验值,因此根据思路1,我们也可以对整个apk包做哈希校验。

       通过检查apk包的MD5摘要值来判断代码文件是否被篡改的java实现代码如下图所示:

[java] view plain copy
 
  1. /** 
  2.  * 通过检查apk包的MD5摘要值来判断代码文件是否被篡改 
  3.  * 
  4.  * @param orginalMD5 原始Apk包的MD5值 
  5.  */  
  6. public static void apkVerifyWithMD5(Context context, String orginalMD5) {  
  7.     String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径  
  8.     try {  
  9.         MessageDigest dexDigest = MessageDigest.getInstance("MD5");  
  10.         byte[] bytes = new byte[1024];  
  11.         int byteCount;  
  12.         FileInputStream fis = new FileInputStream(new File(apkPath)); // 读取apk文件  
  13.         while ((byteCount = fis.read(bytes)) != -1) {  
  14.             dexDigest.update(bytes, 0, byteCount);  
  15.         }  
  16.         BigInteger bigInteger = new BigInteger(1, dexDigest.digest()); // 计算apk文件的哈希值  
  17.         String sha = bigInteger.toString(16);  
  18.         fis.close();  
  19.         if (!sha.equals(orginalMD5)) { // 将得到的哈希值与原始的哈希值进行比较校验  
  20.             Process.killProcess(Process.myPid()); // 验证失败则退出程序  
  21.         }  
  22.     } catch (NoSuchAlgorithmException e) {  
  23.         e.printStackTrace();  
  24.     } catch (FileNotFoundException e) {  
  25.         e.printStackTrace();  
  26.     } catch (IOException e) {  
  27.         e.printStackTrace();  
  28.     }  
  29. }  

 

思路3:对签名文件中classes.dex哈希值的校验

        Android工程代码经编译打包生成apk包后,开发者需要对其签名才能在安卓市场上发布供用户下载和安装。对apk包签名后,会在原apk包结构基础上加入META-INF文件目录。签名后的apk包文件目录如下图所示:

       META-INF文件目录下含有三个文件:MANIFEST.MF文件、ANDROIDD.SF文件、ANDROIDD.RSA文件,META_INF目录文件结构如下图所示:

       其中,MANIFEST.MF文件描述了在签名时,签名工具对apk包中各个文件摘要计算后的哈希值,并对哈希值做了Base64编码。MANIFEST.MF文件中描述的classes.dex文件的SHA-1哈希值如下图所示:

       一旦攻击者对APK中反编译并篡改代码,经二次打包签名后的classes.dex文件的SHA-1必定改变,因此,我们可以将该文件中的classes.dex文件的SHA-1哈希值保存起来作为校验对比值,应用程序启动时读取apk安装包中的MANIFEST.MF文件,解析出classes.dex的SHA-1哈希值,然后与原SHA-1哈希值进行比较,判断此APK包代码文件是否被篡改。

       通过检查签名文件classes.dex文件的哈希值来判断代码文件是否被篡改的java实现代码如下所示:

[java] view plain copy
 
  1. /** 
  2.  * 通过检查签名文件classes.dex文件的哈希值来判断代码文件是否被篡改 
  3.  * 
  4.  * @param orginalSHA 原始Apk包的SHA-1值 
  5.  */  
  6. public static void apkVerifyWithSHA(Context context, String orginalSHA) {  
  7.     String apkPath = context.getPackageCodePath(); // 获取Apk包存储路径  
  8.     try {  
  9.         MessageDigest dexDigest = MessageDigest.getInstance("SHA-1");  
  10.         byte[] bytes = new byte[1024];  
  11.         int byteCount;  
  12.         FileInputStream fis = new FileInputStream(new File(apkPath)); // 读取apk文件  
  13.         while ((byteCount = fis.read(bytes)) != -1) {  
  14.             dexDigest.update(bytes, 0, byteCount);  
  15.         }  
  16.         BigInteger bigInteger = new BigInteger(1, dexDigest.digest()); // 计算apk文件的哈希值  
  17.         String sha = bigInteger.toString(16);  
  18.         fis.close();  
  19.         if (!sha.equals(orginalSHA)) { // 将得到的哈希值与原始的哈希值进行比较校验  
  20.             Process.killProcess(Process.myPid()); // 验证失败则退出程序  
  21.         }  
  22.     } catch (NoSuchAlgorithmException e) {  
  23.         e.printStackTrace();  
  24.     } catch (FileNotFoundException e) {  
  25.         e.printStackTrace();  
  26.     } catch (IOException e) {  
  27.         e.printStackTrace();  
  28.     }  
  29. }  

 

       以上三种完整性校验实现思路的实现代码样例采用Java语言实现,从安全角度来讲,很容易通过反编译篡改patch掉,因此在实现完整性校验代码时还需参考以下几点建议:

       1.预先计算的dex文件的哈希值、签名文件的classes.dex的SHA-1哈希值,应避免直接明文硬编码存储在代码或配置文件中,可对其采用非对称加密存储,或采取与服务端通信的方式获取。

       2.由于dex文件很容易通过dex2jar、apktool反编译后逆向分析和破解,因此该完整性校验功能可进一步使用C/C++代码进行编写实现。另外,进一步提高安全性,还可通过源码混淆,如:开源的obfuscator-llvm项目,或对.so动态库加壳,增加逆向分析和破解的难度。

分享到:
评论

相关推荐

    10--[身份证校验码计算器].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码

    10--[身份证校验码计算器].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码10--[身份证校验码计算器].zip源码scratch2.0 3.0编程项目源文件源码案例素材源代码10--[身份证校验码计算器].zip源码scratch2.0 ...

    Android代码-Android表单校验功能

    ValidationUtilsLibrary The goal of this library is to help you in your development of validation forms. currently it works on follow entities: First name: if first name is blank or other than ...

    游戏文件完整性校验工具

    游戏文件完整性校验工具游戏文件完整性校验工具游戏文件完整性校验工具

    一个完整无误的CRC-16循环校验(汇编)

    一个完整无误的CRC-16循环冗余校验MCS-51汇编源代码 技术知识 2009-10-10 11:44:13 阅读116 评论0 字号:大中小 网上提供的CRC-16循环冗余校验很多,但几乎没有一个完全正确的,参考网上的做了一些修改便通过了,...

    javascript实例应用---密码校验类.rar

    javascript实例应用---密码校验类.rarjavascript实例应用---密码校验类.rarjavascript实例应用---密码校验类.rarjavascript实例应用---密码校验类.rar

    Android代码-NextInputs-Android

    > NextInputs-Android 是一个为Android表单实现的校验库,它提供了非常丰富的接口和内置组件,可以为你方便快捷地接入表单校验功能。 项目结构 inputs Inputs校验核心模块,实现校验库的整体架构;见: Inputs ...

    java完整性校验解决方案

    JAVA中进行数据完整性验证 最近在看JAVA安全方面的东东。简单地说,安全包括访问控制、数据安全两部分。安全访问控制是根据系统需求进行设计的,对资源进行访问控制的一种措施。而数据安全包括数据传输过程中的安全...

    移动安全系列教学下载共43份.zip

    Android安全安全技术--21--Android应用安全防护技术.pdf Android安全安全技术--22--其他Android安全知识总结.pdf Android安全安全技术--34--Emulator模拟器的配置和ROOT(终极版).pdf Android安全应用逆向--23--反...

    文件完整性校验工具.exe

    文件完整性校验工具.exe

    基于C++实现 MD5 算法的文件完整性校验程序【100010122】

    基于 MD5 算法的文件完整性校验程序,本实验使用 C++ 语言在 Linux 平台进行编程和运行。 ./md5 -h 查看帮助 ./md5 -t 打印程序的测试信息 ./md5 -c nankai.txt 计算出的被测文件的 MD5 摘要并打印 ./md5 -v nankai....

    Linux文件完整性校验检查方案AIDE

    AIDE是开源的Linux文件完整性校验检查方案,可用于传输或关键敏感信息保护,提高系统安全性保护。 资源包中提供了AIDE的完整代码。

    struts框架验证---输入校验器大全

    struts框架验证---输入校验器大全

    cyberplayer-去除ak校验

    支持Flash与HTML5两种模式 支持广泛的流式视频格式,支持FLV/MP4等格式的渐进式和... 支持加密视频播放,播放内核实现了对AES128加密的HLS视频进行解密和播放,便于企业用户对视频内容进行加密保护。 支持多码率视频

    CHK(文件完整性校验工具) v1.85.zip

    CHK(文件完整性校验工具)可以验证文件的完整性让你可以查看到你的文件的大小、类型和sha等等信息,CHK可以帮你核对你的文件信息比较复制/传输的文件,还可以查找和从计算机中删除重复的文件软件特色。 CHK(文件完整...

    QBJ-903转速校验台手册.doc

    QBJ-903转速校验台手册doc,QBJ-903转速校验台手册

    完整性校验

    完整性校验sha1算法,能够很好的了解完整性校验的过程原理

    构建安全的Android客户端请求.zip

    该压缩文件包含了两个工程——一个Java Web工程,一个Android客户端工程,这两个工程将详细介绍如何构建安全的Android客户端请求,避免非法请求,欢迎下载

    【PTA】【作者: 赵冲 单位: 厦门大学】7-1 身份证校验_python

    中国居民身份证校验码算法如下: 将身份证号码前面的17位数分别乘以不同的系数。从第一位到第十七位的系数分别为:7-9-10-5-8-4-2-1-6-3-7-9-10-5-8-4-2。 将这17位数字和系数相乘的结果相加。用加...

    YHS-787过程校验多用表.rar

    YHS-787过程校验多用表rar,YHS-787过程校验多用表产品说明书

Global site tag (gtag.js) - Google Analytics