注意:本篇文章是本人阅读相关文章的总结,方便以后查阅,所有内容非原创,侵权删。
本篇文章内容来自于
1.Android高级进阶 顾浩鑫
2.相对应的知识块的最下方会给出原来的帖子的链接
前言
Android经常遇到需要在客户端对一些敏感信息进行保存,例如开源库SQLCipher对数据库进行加密,用Facebook的Conceal对磁盘上大文件的加密。也会涉及加密所用的密钥如何在客户端安全存放的问题。
敏感信息有:
1.加密所用的密钥
2.第三方SDK官方网站的API Key
3.用户密码、手机号、快捷支付手机号、Email、身份证、银行卡等私人信息。
如何在客户端保存敏感信息,是关系到整个APP是否安全的关键问题。
常见的敏感信息隐藏策略主要有
1.敏感信息嵌套在strings.xml中
2.敏感信息隐藏在Java源代码中
3.敏感信息隐藏在BuildConfig中
4.使用DexGuard
5.对敏感信息进行伪装或者加密
6.敏感信息隐藏在原生函数库中(.so文件)
7.对APK进行加固处理
目录
1.敏感信息嵌套在strings.xml中
2.敏感信息隐藏在Java源代码中
3.敏感信息隐藏在BuildConfig中
4.使用DexGuard
5.对敏感信息进行伪装或者加密
6.敏感信息隐藏在原生函数库中(.so文件)
7.对APK进行加固处理
1. 敏感信息嵌套在strings.xml中
最常见的一种方式:存在工程的res/values/strings.xml中
但是安全性极低,对方只需要使用ApkTool等工具对APK的资源文件进行反编译,就可以轻松拿到。
123456
2.敏感信息隐藏在Java源代码中
同样常用的方式:将密钥或者API Key以字符串或者字符数组的形式硬编码到代码中
但是安全性也很低,通过dex2jar和JD-GUI反编译可以看到源码
private static final String STATIC_KEY = "123456";
//以字符数组形式存放,比字符串形式安全。
private static final byte[] KEY_ARR = new byte[]{'1','2','3','4','5','6'};
3.敏感信息隐藏在BuildConfig中(BuildConfig+gradle.properties)
可参考BuildConfig的使用
我们可以将敏感信息存放在BuildConfig文件,同时通过将敏感信息存放在工程中的gradle.properties中,可以避免将其上传到版本控制系统(svn或者git上),从而将敏感信息控制在少数人手里,而不是暴露给所有svn或者git权限的人。
但是安全级别也是很低的,我们可以对生成的APK反编译,查看BuildConfig.class文件,还是可以看到API Key的取值。
第一步:在app/build.gradle设置BuildConfig
android {
...
buildTypes {
release {
minifyEnabled true
proguardFiles getDefaultProguardFile('proguard-android.txt'), 'proguard-rules.pro'
//buildConfigField用于给BuildConfig文件添加一个字段
buildConfigField("String","KEY","\"${AppKey}\"")
}
debug{
buildConfigField("String","KEY","\"${AppKey}\"")
}
}
...
}
第二步:""${AppKey}""取值定义在gradle.properties文件中。
AppKey=123456
第三步:使用
Log.d("xl",BuildConfig.KEY);
4.使用DexGuard
Android默认集成了ProGuard,它是一个免费的用于压缩、优化和混淆Java字节码的工具,混淆的功能主要是用简短的无意义的字母组合来对代码中的类、字段、方法和属性进行重命名,但它无法对字符串进行混淆。
即使用Proguard后,我们还是可以看到反编译后代码中完整的字符串定义。
我们可以选择商业版的Proguard-DexGuard。DexGuard对代码、资源、字符串、AndroidManifest.xml等进行了全面的加密和混淆。
5.对敏感信息进行伪装或者加密
虽然DexGuard功能强大,也能帮助我们对敏感字符串信息进行加密,但毕竟需要支付费用。
因此绝大多数情况下,只能靠我们自己对java代码中的敏感信息进行加密,以加大第三方破解的难度。
参考待放
6.敏感信息隐藏在原生函数库中(.so文件)
为了增大第三方获取敏感信息的难度,我们可以进一步吧敏感信息的存放从Java层下移到Native层,也就是放在.so文件中。然后通过jni封装对敏感信息的获取接口。
至于敏感信息在C/C++层如何存放,我们可以重复Java层的伪装和加密方式。
另外可在C/C++层通过指令的方式使得反汇编.so文件的时候出错,来增加.so文件被破解的难度。
参考待放
7.对APK进行加固处理
现在出现了很多APK的加固平台。
APK的加固处理极大地增加了反编译的难度。经过加固平台的加固后,想使用普通的dex2jar、ApkTool等工具进行反编译几乎都是失败的,从而让他人无法轻易得到APP的代码和资源。
参考Android加固