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