加密技術(shù)是最常用的安全保密手段,利用技術(shù)手段把明文變?yōu)槊芪模用埽﹤魉停竭_目的地后再用相同或不同的手段還原(解密)。常見的加密算法可以分成三類,對稱加密算法,非對稱加密算法和HASH算法。前兩類是可逆的,即加密后的密文仍然可以轉(zhuǎn)換成明文,但Hash算法是不可逆的,即使在有源碼及密文的情況下也無法將明文還原出來,如MD5算法。
由于Java的語言特點及Android的開放性質(zhì),出現(xiàn)了越來越多的惡意程序。谷歌Android市場在也曾多次遭惡意開發(fā)者上傳基于正常應(yīng)用篡改后的惡意軟件,雖然這些軟件已經(jīng)被查出,但在將其下架前已經(jīng)造成了幾十萬用戶被感染。這些惡意程序都是以已存在的成名的應(yīng)用為載體,經(jīng)過二次處理后植入惡意代碼,重新簽證后再次向市場發(fā)布,誘導(dǎo)用戶下載使用。為了避免這種情況的發(fā)生,保護自己的應(yīng)用在未經(jīng)自己允許的情況下慘遭篡改,保護自己的應(yīng)用不會被人利用做一些傷害用戶的行為,本章節(jié)中將介紹這樣一種保護機制。
Android系統(tǒng)要求每一個安裝進系統(tǒng)的應(yīng)用程序都是經(jīng)過數(shù)字證書簽名的,數(shù)字證書的私鑰(即.keystore簽證文件)則保存在程序開發(fā)者的手中,簽證后的信息摘要保存在APK包中的.RSA文件中。數(shù)字證書用來標識應(yīng)用程序的作者與應(yīng)用程序之間建立信任關(guān)系。一旦證書被篡改,則.RSA文件被替換了,即表明應(yīng)用程序的原作者不再為該應(yīng)用負責。依照這個原理,可以在第一次運行程序時讀取APK中的.RSA摘要信息對其進行判斷是否是與經(jīng)應(yīng)用原作者簽名后產(chǎn)生的信息一致。如果一致則讓程序正常運行;如果不一致則表明應(yīng)用被篡改過,提示用戶并終止運行。
可以通過以下方法獲取APK包中的.RSA信息:
1 | Signature[] sigs = getPackageManager().getPackageInfo(getPackageName(), PackageManager.GET_SIGNATURES).signatures; |
2 | byte[] data = sigs[0].toByteArray(); |
在Android官方文檔中,對Signature類的定義是:在應(yīng)用程序包及對該包進行簽名的證書間建立起不透明的、不可改變的代表關(guān)系。執(zhí)行Signature.toByteArray()將返回.RSA的字節(jié)信息。
下面將把這些字節(jié)轉(zhuǎn)換成可閱讀的數(shù)字指紋信息:
2 | MessageDigest algorithm = MessageDigest.getInstance(alg); |
3 | // 將狀態(tài)重圍到初始化,準備好進行計算Hash值。 |
7 | // 將Hash值轉(zhuǎn)為可讀的16進制文本 |
8 | byte[] dataHash = algorithm.digest(); |
通過MessageDigest來計算數(shù)字指紋信息,其算法核心是HASH函數(shù)。哈希函數(shù)提供了這樣一種計算過程:輸入一個長度不固定的字符串,返回一串定長度的字符串,即HASH值。
HASH函數(shù)主要可以解決以下兩個問題:一是無法通過HASH值得到原報文;二是不存在不同報文經(jīng)HASH操作后生成相同HASH值。
這樣在數(shù)字簽名中就可以解決驗證簽名和用戶身份驗證、不可抵賴性的問題。在獲取MessageDigest時要指定所使用的算法名稱,常見的算法是專門用于加密處理的MD5和SHA1。這兩種算法產(chǎn)生一種128位信息摘要,除徹底地搜尋外,沒有更快的方法對其加以攻擊,而其搜索時間一般需要1025年之久,這樣即可保證信息在一段時間內(nèi)的有效性與安全性。
使用MessageDigest時,養(yǎng)成一個良好的習慣是在讀取數(shù)據(jù)前將其reset()置初始化狀態(tài),即使這個實例是剛實例化的,這樣盡量可以避免之前已讀的冗余數(shù)據(jù)對最后的結(jié)果產(chǎn)生負作用。接下來就是使用update()方法讀取待計算的數(shù)據(jù),完成后調(diào)用digest()將返回計算后的HASH值dataHash數(shù)組。最后為了可讀性,通過自己實現(xiàn)的toHexString()把HASH值由byte轉(zhuǎn)為16進制文本。
在得到dataHash時,即可對應(yīng)用程序是否正版進行判斷了,但一般為了簡便,把提前寫入的正版的指紋信息與最后HexString值進行比較,從而得出應(yīng)用程序是否被篡改的結(jié)果。比較代碼如下:
01 | txtVerify.setText(alg + '\n'); |
03 | String result = 'This soft is a pirated software.'; |
06 | txtVerify.append('Original:' + '\n' + HASH_VALUE_MD5 + '\n'); |
07 | if (HASH_VALUE_MD5.equals(hexInfo)) { |
08 | result = 'This soft is a genuine software'; |
10 | } else if (alg.equals(SHA1)) { |
11 | txtVerify.append('Original:' + '\n' + HASH_VALUE_SHA1 + '\n'); |
12 | if (HASH_VALUE_SHA1.equals(hexInfo)) { |
13 | result = 'This soft is a genuine software'; |
17 | txtVerify.append('Current:' + ':\n' + hexInfo + '\n'); |
18 | txtVerify.append(result); |
以上代碼中的HASH_VALUE_MD5和HASH_VALUE_SHA1分別是使用Code_Test_Key.keystore簽名后的APK實際計算出的HASH值。
Demo運行效果如下:

圖17-1 驗證MD5值

圖17-2 驗證SHA1值
Demo源代碼下載: Code_Test.rar(825.11 KB, 下載次數(shù): 308, 售價: 1 資源分) 2012-8-3 16:34:55 上傳 下載次數(shù): 308 售價: 1 資源分 [記錄] [ 購買]
|