Android加固包簽名
我們知道自己的apk在上傳市場(chǎng)的時(shí)候, 為了更好的包含我們的代碼需要加固服務(wù), 加固后的apk是不能直接安裝的, 需要我們手動(dòng)簽名.
關(guān)于Android簽名的知識(shí)就不在贅述了,網(wǎng)上有很多相關(guān)內(nèi)容. Android應(yīng)用數(shù)字簽名詳解
重點(diǎn)我們需要知道:
- android的簽名不是 google自定義的, 它是一個(gè)通用校驗(yàn)算法, 通用與java 應(yīng)用程序發(fā)版中. Android的簽名只是在該算法基礎(chǔ)上提供了自己的工具;
- 我們可以使用android studio 方便的完成對(duì)apk的簽名,同事也可以使用其他簽名工具對(duì)apk進(jìn)行簽名.
那么如何多已加固的包進(jìn)行簽名呢? 我們可以使用jarsigner 工具, 這個(gè)事jdk自帶的簽名工具, 將keystore文件(或者jks文件) 作為輸入的簽名文件來(lái)對(duì)apk進(jìn)行簽名.
另一個(gè)是工具signapk工具進(jìn)行簽名, signapk是Android中提供的工具,其簽名輸入文件為xxx.pk8和xxx.x509.pem. signapk簽名apk
keystore 簽名文件中是可以提取signapk工具需要的簽名文件的 詳見(jiàn)keystore文件轉(zhuǎn)換格式為pk8+x509.pem
介紹了上述關(guān)于android簽名的內(nèi)容, 今天的重點(diǎn)是放出一個(gè)通過(guò)jarsigner 簽名加固寶的python腳本.
#coding=utf-8
import os, sys
# 你的jks文件名稱(chēng)
jksname = "jskfilename.jks"
# 注意yourpass 需要配置為你自己的密碼
signerformat = "jarsigner -verbose -sigalg SHA1withRSA -storepass yourpass -digestalg SHA1 -keystore '{jksfile}' -signedjar '{signedpath}' '{unsignedpath}' wujikeji"
zipalignformat = "zipalign -v -f 4 '{signedapk}' '{alignedapk}'"
if __name__ == "__main__":
cur_path = sys.path[0]
for parent, dirnames, filenames in os.walk(cur_path):
if parent == cur_path:
for filename in filenames:
print os.path.join(parent, filename)
# 過(guò)濾非apk文件以及已簽名apk
if filename.endswith(".apk") and "signed" not in filename:
# 提取文件名標(biāo)示
apktag = filename.replace("app","").replace("-","").\
replace(".","").replace("release","").\
replace("apk","").replace("_","").replace("encrypted","").replace("legu","")
jksfile = os.path.join(cur_path, jksname)
signedpath = os.path.join(cur_path, apktag+"_signed.apk")
# 簽名apk
os.popen(signerformat.format(jksfile=jksfile, signedpath=signedpath, unsignedpath=os.path.join(parent,filename)))
alignedapk = os.path.join(cur_path, apktag+"_signed_zipaligned.apk")
# 對(duì)其apk
os.popen(zipalignformat.format(signedapk = signedpath, alignedapk = alignedapk))
# 刪除中間文件
os.remove(signedpath)
pass
該腳本針對(duì)加固后的包進(jìn)行批量簽名, 將加固后apk包和簽名文件(jks文件)放入該腳本文件相同目錄下, 運(yùn)行腳本即可得到簽名并對(duì)其的apk包. 前提需要配置自己的密碼.
渠道包測(cè)試
渠道生成之后按理說(shuō)應(yīng)該可以直接發(fā)不了,但對(duì)于一般的程序猿都會(huì)多多少少有點(diǎn)強(qiáng)迫癥, 要每個(gè)渠道都安裝運(yùn)行一下, 不需要多么詳細(xì)的測(cè)試, 只是看下每個(gè)應(yīng)用能不能運(yùn)行起來(lái).
國(guó)內(nèi)十多個(gè)市場(chǎng), 每個(gè)市場(chǎng)對(duì)應(yīng)一個(gè)渠道包, 僅這些渠道包的簡(jiǎn)單測(cè)試就話(huà)費(fèi)了好長(zhǎng)時(shí)間. 并且每次有不需要多么仔細(xì)的測(cè)試. 于是想到直接用adb 控制手機(jī)自動(dòng)完成測(cè)試的方法.
使用python作為控制腳本, 直接上代碼:
import os, sys, time
adb_start_cmd ="adb shell am start -n pkgname/launchActivity"
adb_install_format = "adb install '{apk_path}'"
adb_uninstall = "adb uninstall yourpackagename"
if __name__ == "__main__":
cur_path = sys.path[0]
for parent, dirnames, filenames in os.walk(cur_path):
if parent == cur_path:
all_apk_num = len(filenames) -2
cur_count = 0;
for filename in filenames:
# 過(guò)濾非apk文件以及已簽名apk
if filename.endswith(".apk") :
cur_count +=1
print filename
# 提取文件名標(biāo)示
apktag = filename.replace("app","").replace("-","").\
replace(".","").replace("release","").\
replace("apk","").replace("_","").replace("encrypted","").replace("legu","")
os.popen(adb_uninstall)
os.popen(adb_install_format.format(apk_path=os.path.join(cur_path, filename)))
print apktag + "\t" + str(cur_count)+"/"+str(all_apk_num)
print "monkey go:"
os.popen(adb_start_cmd)
# 通過(guò)adb shell input 命令,先將首次啟動(dòng)頁(yè)跳過(guò)
time.sleep(5)
os.popen("adb shell input swipe 800 200 50 200")
time.sleep(1)
os.popen("adb shell input tap 300 300")
time.sleep(1)
os.popen("adb shell input keyevent 4")
os.popen("adb shell input keyevent 4")
# 真正放候啦
# os.popen("adb shell monkey -p com.rong.jieqian.daikuanba -v 20 --throttle 1000 --pct-touch 50% --pct-trackball 25% --pct-motion 25%")
os.popen("adb shell monkey -p com.rong.jieqian.daikuanba -v 2000")
raw_input("input anything to continue: ")
代碼主要用到三方面知識(shí):
- adb 控制應(yīng)用程序, 實(shí)現(xiàn)自動(dòng) 安裝, 卸載和啟動(dòng);
- android 系統(tǒng)中的input 命令工具; 能夠?qū)崿F(xiàn)一些事件的輸入, 在上面代碼中實(shí)現(xiàn)了一個(gè)
input swipe用于模擬滑動(dòng)事件 和一個(gè)input tap用于模擬點(diǎn)擊事件. - android系統(tǒng)中 monkey 命令工具; 能夠隨機(jī)生成一些列的輸入事件, 就像猴子亂按一樣.