`
shuai1234
  • 浏览: 977556 次
  • 性别: 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动态库加壳,增加逆向分析和破解的难度。

分享到:
评论

相关推荐

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

    在构建安全的Android客户端请求时,开发者需要关注多个层面的安全问题,以确保用户数据的完整性和隐私不被侵犯。这份"构建安全的Android客户端请求.zip"压缩包可能包含了一个Java Web后端服务和一个Android客户端...

    android客户端de登录注册源代码

    这个"android客户端de登录注册源代码"提供了一个完整的解决方案,将Android客户端与PHP服务器进行交互,实现用户的身份验证和数据管理。这里我们将深入探讨相关知识点。 1. **Android客户端开发**: - **Activity*...

    Android客户端访问web服务器

    HTTP是超文本传输协议,用于传输数据,而HTTPS是在HTTP基础上加入了SSL/TLS安全层,提供了加密处理、服务器身份验证和消息完整性校验,确保数据传输的安全性。 2. **Android网络请求库**:Android原生API虽然可以...

    Android-SpringBoot-MyBatis-RESTful-登录注册修改密码Demo

    - **RESTful API设计**: 使用HTTP方法(GET、POST、PUT、DELETE等)和URI资源定位,遵循REST原则,为Android客户端提供服务。 3. **MyBatis框架**: - **MyBatis**: 是一个持久层框架,简化了Java对象与数据库表...

    Android开发中使用CRC校验.rar

    在Android应用开发中,CRC(Cyclic Redundancy Check,循环冗余校验)是一种广泛使用的错误检测方法,主要用于确保数据传输或存储的完整性。CRC校验通过计算数据的二进制位序列来生成一个固定长度的校验码,这个校验...

    有人软件--c#-android-ios-VB-实现mudusudp和tcp.rar--RS485

    -c#-android-ios-VB-实现mudusudp和tcp.rar--RS485”指的是一个包含多种编程语言(C#、Android、iOS、VB)实现MudBus协议的示例代码的压缩包,该协议基于UDP和TCP网络通信方式,并涉及RS485串行通信技术。...

    面向Android应用程序的代码保护方法研究.pdf

    通过文件加密、代码混淆、反动态调试、完整性校验以及加壳等技术,有效增强了Android应用的安全性。 总的来说,这个面向Android应用程序的代码保护方法不仅具有理论意义,还具有实际应用价值。它能够帮助开发者提高...

    Android-validate-SSL-certificate-example:android 如何安全的去校验ssl证书

    客户端需要检查该证书是否由已知的、可信赖的CA签发,证书链是否完整,以及证书的有效期等信息。如果验证失败,客户端应拒绝建立连接。 在Java编程语言中,我们可以利用`java.security.cert`和`javax.net.ssl`这两...

    android 拍照 录像 本地文件上传客户端 服务端

    - 需要处理多线程接收、文件完整性校验、权限控制等问题。 7. **安全与性能优化**: - 上传前对文件进行加密,保护用户数据的安全。 - 使用断点续传技术,提高大文件上传的稳定性。 - 分块上传可提高上传效率,...

    支付宝 Android 架构

    - **安装、升级合法性校验**:通过签名和依赖关系校验来确保模块的合法性和兼容性。 #### 研发支撑 支付宝Android客户端的研发流程包括: - **研发过程**:从需求分析到上线的完整流程。 - **构建过程**:自动化...

    A/B分区系统ota更新客户端代码 SystemUpdate.zip

    综上所述,A/B分区系统ota更新客户端代码涉及的关键技术包括Android系统的A/B分区机制、OTA更新流程、差分包的运用以及Java编程和XML资源配置。这些内容对于理解Android设备的系统更新过程和开发相关的更新工具至关...

    基于SM3的Android文件完整性检测系统.pdf

    SM3算法,全称为“Simple Hash-based Message Authentication Code with 256-bit Output”,是中国自主研发的一种密码散列函数,适用于数字签名、消息认证码(MAC)以及文件完整性校验等领域。它具有高安全性、快速...

    Android图片上传 服务器端客户端源码

    本资源包含了一个完整的Android图片上传解决方案,包括服务器端和客户端的源代码。以下是关于这个主题的详细知识点: 1. **Android客户端部分**: - **图片选择**:Android客户端通常会提供一个图片选择器,让用户...

    Android C/S结构代码

    为了确保图片数据的完整性和正确性,通常需要在数据传输前进行编码和压缩,如使用JPEG或PNG格式,并且可以考虑添加校验和或使用SSL/TLS进行加密,以增强数据的安全性。 在Android端,考虑到内存和性能,我们可能...

    Android插件化及动态部署 - ATLAS 共16页.pptx

    此外,为了保证安全性,ATLAS还引入了插件的完整性校验和版本管理,确保每个插件的可信性。 在插件化过程中,解决兼容性、安全性和数据共享问题至关重要。ATLAS框架提供了丰富的机制来处理这些问题。例如,它支持...

    Android应用源码之安卓图片上传和文件上传带jsp服务端源码.zip

    可以限制上传文件的大小和类型,使用MD5或SHA校验和确保文件完整性。 - 为了提升用户体验,可以采用断点续传、分块上传等策略,尤其是在上传大文件时。 这份源码提供了从Android客户端到服务器端的完整图片和文件...

    加入数据库mysql实现android注册登陆功能的客户端服务器源码与解析

    在源码中,`加入数据库mysql实现android注册登陆功能的客户端服务器源码与解析.zip`包含了完整的Android客户端代码和服务器端PHP脚本。`README.md`文件应该提供了关于如何构建和运行这些代码的详细步骤,包括设置...

    Android代码-NetWrapper

    md5校验 : 是否预先提供md5 ,下载完后与文件md5比较,以确定所下载的文件的完整性? * 5.断点续传的实现 6.下载队列和指定同时下载文件的个数 * */ 2.缓存 无网络时读缓存 缓存文件夹大小的设置 缓存功能改回由...

    App安全检测指南-V1.0-t00ls

    本文档提供了关于 APP 安全检测的基本框架,涵盖了安装包签名、反编译保护和应用完整性校验三个重要方面。通过对这些方面的深入理解和实施,可以帮助提高 APP 的安全性,减少潜在的安全威胁。需要注意的是,安全检测...

    Android应用安全加固关键技术研究.pdf

    3. 静态防御技术:使用 DexClassLoader 对 dex 文件进行动态加载,使用签名校验对应用的签名进行检测,使用完整性校验对原始代码进行检测,使用资源文件混淆对资源文件进行混淆。 4. 动态防御技术:使用反射技术对...

Global site tag (gtag.js) - Google Analytics