Android开发中经常会遇到需要在客户端对一些敏感信息进行保存的情况,客户端的加密信息,关系到整个App是否安全的关键问题。
常见的敏感信息隐藏策略主要有:
1、敏感信息嵌套在string.xml中
安全性极低,第三方只需要使用ApkTool等工具对Apk的资源进行反编译,就能轻易地拿到这个资源文件,里面的内容是一目了然的。
2、敏感信息隐藏在Java源代码中
将密钥或者app_key 以字符串或者字符数组的形式硬编码到代码中,这也是普通开发者常用的方式
反编译可以得到classes-dex2jar.jar 包,这时使用JD-GUI 可以查看反编译后的源码。
3、敏感信息隐藏在BuildConfig中
Android Gradle Plugin 为我们提供了BuildConfig 文件,我们可以把敏感信息存在这里,同时通过将敏感信息存放在工程的gradle.properties中,可以避免将其上传到版本控制系统(svn、git)上,从而将敏感信息控制在少数人手里,而不是暴露给所有具有svn、git 权限的人。
这种方式安全级别也是比较低的,对apk进行反编译以后,查看BuildConfig.class 文件就可以看到APP_KEY 的值。
4、使用DexGuard
Android 官方默认集成了ProGuard,它是一个免费的用于压缩、优化和混淆Java 字节码的工具,混淆的功能主要是使用简短的无意义的字母组合来对代码中的类、字段、方法和属性进行重命名,但它无法对字符串进行混淆。也就是说,使用ProGuard之后,我们还是可以看到反编译后代码的完整的字符串定义。
为了实现更高级的混淆和加密功能,我们可以选择商业版本的ProGuard-DexGuard.
DexGuard对代码、资源、字符串、AndroidManifest.xml等进行了全面的加密和混淆,相对PorGuard,功能强大了不少。
5、对敏感信息进行伪装或者加密
虽然DexPuard功能强大,也能帮助我们对敏感字符串信息进行加密,但毕竟需要付费试用,并不是每个公司都会愿意付费。因此多数情况下,只能靠我们自己对Java代码中的敏感信息进行伪装或者加密,以加大第三方破解的难度。最简单的我们可以试用Base64对字符串进行编码,然后将编码后的字符串和另外一串密钥进行异或操作,从而得到伪装后的字符串。当然,这个用于异或的密钥如何存放,就是一个先有鸡还是先有蛋的问题了。
6、敏感信息隐藏在原生函数库中(.so文件)
为了增大第三方获取敏感信息的难度,我们可以进一步把敏感信息的存放从Java 层下移到Native 层,也就是存放在.so 文件中。然后通过jni 封装对敏感信息的获取接口。至于敏感信息在c/c++层如何存放,我们可以重复Java层的伪装和加密方式,另外可以在c/c++层通过花指令的方式来使得反汇编.so 文件的时候出错,来增加.so文件被破解的难度。
7、对APK 进行加固处理
近年来,涌现了很多APK 加固平台,APK的加密处理极大地增加了反编译的难度,经过加固平台的加固后,想使用普通的dex2jar、ApkTool 等工具进行反编译几乎都是失败的,这使得普通开发者再也无法轻易地偷窥发布在应用市场的app 代码或者资源了。