Android安全問題-網(wǎng)絡(luò)傳輸
Android開源,開源就意味著無線可能和無線的不安全。現(xiàn)在(2016)市面上的所有Android安全方法基本上有以下幾種:
1.代碼混淆。
2.so處理重要邏輯。
3.加殼
這些都是在客戶端做的處理,然而,如果破解客戶端能獲取的利益大于破解的難度,那么基于開源的Android基本還是會被'破解大軍'進行'三光政策'的。既然都會被破解,那還做這些做什么呢?這就是我之前文章說的,利益和難度的取舍。當(dāng)我們做了以上3部后,就已經(jīng)阻絕絕大部分的'破解軍',剩下的哪些頂尖人物怎么辦呢?現(xiàn)在我的處理方法是放在服務(wù)端。
問題要解決問題,首先要有問題,那么對于客戶端來說什么是危險的呢?舉個栗子,當(dāng)用戶注冊的時候,如果明文傳輸就有可能被攔截到,泄漏用戶密碼的問題。正對這個問題,我來敘述一下自己的解決方案,順便把這篇文章的重點帶出來。
解決問題:用戶注冊和服務(wù)端交互的信息有可能被攔截,導(dǎo)致賬戶等信息泄露。
方法1
將用戶密碼進行MD5后再傳遞。
這種方法也就保證了我們自己也無法知道用戶的密碼是什么。即使被攔截,破解軍獲取到這段信息也無法得知密碼是什么。
PS:這種方法是可取的,但是如果用戶的密碼比較簡單,那也是可以通過暴力破解出來的。所以MD5的方法比較適合用來確保數(shù)據(jù)的正確性,而不適合作為數(shù)據(jù)的保密處理。
方法2
使用特殊算法進行加密后在傳遞。
這種方法可以確保即使被攔截到信息,在不知道我們算法的前提下,破解軍也無法獲取有用信息。
不過這里有兩個問題,第一是算法在破解后很容易查詢到,即使是存放在so文件中。第二是這種自己定義算法對性能的要求可能比較高,畢竟我們又不是數(shù)學(xué)專家。
當(dāng)然為了更堅固的堡壘,提高破解軍的成本,該方法是可以結(jié)合使用的。
方法3
使用AES加密報文后在傳遞。
這種方法和方法2類似,只是AES是當(dāng)下確定能很好加密數(shù)據(jù),且很難暴力破解的方案。當(dāng)然加密就要解密,而AES的加密和解密使用的通一個key值。那么就需要客戶端存儲一個key值,既然該key值存在客戶端,那么破解的可能性就很大了。針對這個問題,有一個彎路可以考慮,那就是隱藏key值。
這里就記錄一下隱藏key值的小故事,該方法不單是隱藏key值,也可以隱藏很多東西,增加破解的成本。
好,假設(shè)我們使用了AES加密,那么就有一個key值,那么我們應(yīng)該怎么存這個key在客戶端呢?
方法基本有以下這幾種:
SharedPreferences
Java硬編碼
NDK保存在so
發(fā)現(xiàn),除了NDK的方法有點難度,其它兩種基本都是新手破解軍都能搞定的事,那么怎么辦呢?那我就給他來個大雜燴別(年輕人啊)。首先我把key分成了4份。
key = 'whitelaning';
key1 = 'wh';
key2 = 'ite';
key3 = 'lan';
key4 = 'ing';
當(dāng)需要使用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”)
然后...破解的難度提高了,而且也把以后的開發(fā)者逼瘋了...哈哈...(棄用)
方法4(使用中)
客戶端 --> 服務(wù)端
客戶端使用隨機生成的AES密鑰加密傳輸數(shù)據(jù),使用RSA公鑰加密AES的密鑰。
服務(wù)端使用RSA私鑰解密出AES的密鑰,再使用AES的密鑰解密加密的數(shù)據(jù)。
服務(wù)端 --> 客戶端
服務(wù)端使用RSA解密出AES的密鑰后,使用該AES密鑰解密數(shù)據(jù),然后進行業(yè)務(wù)處理。業(yè)務(wù)處理完畢后,使用該AES密鑰對數(shù)據(jù)進行加密,返回給客戶端。
客戶端接收到返回數(shù)據(jù)后,使用之前請求時隨機生成的AES密鑰進行解析,然后廢棄該AES密鑰。
以上就是一次完整的請求交互過程,當(dāng)然省略了一些細節(jié)上的處理和具體業(yè)務(wù)。比如數(shù)據(jù)應(yīng)該使用MD5來驗證數(shù)據(jù)的完整性,接口驗證等等。
方法4有點類似 SSL/TLS 協(xié)議握手的原理,當(dāng)然因為Android是開源的,沒必要完全按照 SSL/TLS 協(xié)議來實現(xiàn),畢竟做安全問題的時候,我都是默認我的源碼被盜了的情況下去做的。
來自:http://www.jianshu.com/p/84636b4b21d2
相關(guān)文章:
