Android安全问题-网络传输
Android开源,开源就意味着无线可能和无线的不安全。现在(2016)市面上的所有Android安全方法基本上有以下几种:
1.代码混淆。
2.so处理重要逻辑。
3.加壳
这些都是在客户端做的处理,然而,如果破解客户端能获取的利益大于破解的难度,那么基于开源的Android基本还是会被'破解大军'进行'三光政策'的。既然都会被破解,那还做这些做什么呢?这就是我之前文章说的,利益和难度的取舍。当我们做了以上3部后,就已经阻绝绝大部分的'破解军',剩下的哪些顶尖人物怎么办呢?现在我的处理方法是放在服务端。
问题要解决问题,首先要有问题,那么对于客户端来说什么是危险的呢?举个栗子,当用户注册的时候,如果明文传输就有可能被拦截到,泄漏用户密码的问题。正对这个问题,我来叙述一下自己的解决方案,顺便把这篇文章的重点带出来。
解决问题:用户注册和服务端交互的信息有可能被拦截,导致账户等信息泄露。
方法1
将用户密码进行MD5后再传递。
这种方法也就保证了我们自己也无法知道用户的密码是什么。即使被拦截,破解军获取到这段信息也无法得知密码是什么。
PS:这种方法是可取的,但是如果用户的密码比较简单,那也是可以通过暴力破解出来的。所以MD5的方法比较适合用来确保数据的正确性,而不适合作为数据的保密处理。
方法2
使用特殊算法进行加密后在传递。
这种方法可以确保即使被拦截到信息,在不知道我们算法的前提下,破解军也无法获取有用信息。
不过这里有两个问题,第一是算法在破解后很容易查询到,即使是存放在so文件中。第二是这种自己定义算法对性能的要求可能比较高,毕竟我们又不是数学专家。
当然为了更坚固的堡垒,提高破解军的成本,该方法是可以结合使用的。
方法3
使用AES加密报文后在传递。
这种方法和方法2类似,只是AES是当下确定能很好加密数据,且很难暴力破解的方案。当然加密就要解密,而AES的加密和解密使用的通一个key值。那么就需要客户端存储一个key值,既然该key值存在客户端,那么破解的可能性就很大了。针对这个问题,有一个弯路可以考虑,那就是隐藏key值。
这里就记录一下隐藏key值的小故事,该方法不单是隐藏key值,也可以隐藏很多东西,增加破解的成本。
好,假设我们使用了AES加密,那么就有一个key值,那么我们应该怎么存这个key在客户端呢?
方法基本有以下这几种:
SharedPreferences
Java硬编码
NDK保存在so
发现,除了NDK的方法有点难度,其它两种基本都是新手破解军都能搞定的事,那么怎么办呢?那我就给他来个大杂烩别(年轻人啊)。首先我把key分成了4份。
key = 'whitelaning';
key1 = 'wh';
key2 = 'ite';
key3 = 'lan';
key4 = 'ing';
当需要使用key的时候分别获取4段可以值合并后才能得到真正的key。
key1写在string.xml中
mContext().getResources().getString(R.string.something1); 。
ps:为什么叫something1呢,年轻人不懂事...
key2写在AndroidManifest.xml中
<meta-data android:name='something2' android:value='ite'/> 。
key3写在so文件中。
#include 'com_jni_JNIUtils.h' JNIEXPORT jstring JNICALL Java_com_jni_JNIUtils_getString (JNIEnv *env, jobject obj) {
return (*env)->NewStringUTF(env, 'something3');} //--------------------------------------- key3 = new JNIUtils().getString();
key4写在assets的文件中。
Context.getAssets().open(“something4.txt”)
然后...破解的难度提高了,而且也把以后的开发者逼疯了...哈哈...(弃用)
方法4(使用中)
客户端 --> 服务端
客户端使用随机生成的AES密钥加密传输数据,使用RSA公钥加密AES的密钥。
服务端使用RSA私钥解密出AES的密钥,再使用AES的密钥解密加密的数据。
服务端 --> 客户端
服务端使用RSA解密出AES的密钥后,使用该AES密钥解密数据,然后进行业务处理。业务处理完毕后,使用该AES密钥对数据进行加密,返回给客户端。
客户端接收到返回数据后,使用之前请求时随机生成的AES密钥进行解析,然后废弃该AES密钥。
以上就是一次完整的请求交互过程,当然省略了一些细节上的处理和具体业务。比如数据应该使用MD5来验证数据的完整性,接口验证等等。
方法4有点类似 SSL/TLS 协议握手的原理,当然因为Android是开源的,没必要完全按照 SSL/TLS 协议来实现,毕竟做安全问题的时候,我都是默认我的源码被盗了的情况下去做的。
来自:http://www.jianshu.com/p/84636b4b21d2
相关文章: