應(yīng)用程序簽名機(jī)制實(shí)現(xiàn)的源代碼分析
Android采用簽名機(jī)制來保護(hù)應(yīng)用程序的安全,以便于開發(fā)者進(jìn)行身份鑒別,防止替換應(yīng)用程序包和篡改內(nèi)容。同時(shí)有助于在應(yīng)用程序之間建立一種信任,可以由同一個(gè)私鑰簽名的若干個(gè)應(yīng)用程序共享代碼和數(shù)據(jù)。
Android系統(tǒng)簽名主要有ROM簽名和應(yīng)用程序APk簽名兩種形式。ROM簽名是針對(duì)已經(jīng)生成的Android系統(tǒng)ROM包進(jìn)行簽名。應(yīng)用程序APK簽名是針對(duì)開發(fā)者開發(fā)的應(yīng)用程序安裝包APK進(jìn)行簽名。前者是對(duì)整個(gè)Android系統(tǒng)包簽名,后者只對(duì)Android系統(tǒng)中一個(gè)應(yīng)用程序APK簽名。這里僅對(duì)APK簽名的執(zhí)行過程進(jìn)行代碼層面的分析,流程如圖所示。

Android應(yīng)用程序APK是jar包,簽名采用的工具是signapk.jar包,對(duì)應(yīng)用程序安裝包簽名的執(zhí)行命令如下:
Java -jar signapk.jar publickey privatekey input.apk output.apk
此命令實(shí)現(xiàn)了對(duì)應(yīng)用程序安裝包input.apk簽名的功能。在signapk.jar命令中,第一個(gè)參數(shù)為公鑰publickey,第二個(gè)參數(shù)為私鑰privatekey,第三個(gè)參數(shù)為輸入的報(bào)名,第四個(gè)參數(shù)簽名后生成的輸入包名。在此命令中,signapk.jar使用公鑰publickey和私鑰privatekey對(duì)input.apk安裝包進(jìn)行簽名,生成output.apk包。signapk源碼位于build/tools/signapk/SignApk.java中。
完成簽名后APK包中多了一個(gè)META-INF文件夾,其中有名為MANIFEST.MF、CERT.SF和CERT.RSA的三個(gè)文件。MANIFEST.MF文件中包含很多APK包信息,如manifest文件版本、簽名版本、應(yīng)用程序相關(guān)屬性、簽名相關(guān)屬性等。CERT.SF是明文的簽名證書,通過采用私鑰進(jìn)行簽名得到。CERT.RST是密文的簽名證書,通過公鑰生成的。MANIFEST.MF、CERT.SF和CERT.RSA三個(gè)文件所使用的公鑰和私鑰的生成可以通過development/tools/make_key來獲得。下面分被介紹MANIFEST.MF、CERT.SR和CERT.RSA三個(gè)文件生成方法。
(1)生成MANIFEST.MF文件
生成MANIFEST.MF是對(duì)APK包中所有未簽名文件逐個(gè)用算法SHA1進(jìn)行數(shù)字簽名,再對(duì)數(shù)字簽名信息采用Base64進(jìn)行編碼,最后將編完碼的簽名寫MANIFEST.MFWEN文件中。添加數(shù)字簽名到manifest文件通過調(diào)用addDigestsToManifest方法實(shí)現(xiàn),具體代碼如下:
搜索微信公眾號(hào):TestigStudio霍格沃茲的干貨都很硬核