在Android系統中,所有安裝到系統的應用程序都必有一個數字證書,此數字證書用於 標識應用程序的作者和在應用程序之間建立信任關系,如果一個permission的protectionLevel為signature,那么就只有那些 跟該permission所在的程序擁有同一個數字證書的應用程序才能取得該權限。Android使用Java的數字證書相關的機制來給apk加蓋數字證 書,要理解android的數字證書,需要先了解以下數字證書的概念和java的數字證書機制。Android系統要求每一個安裝進系統的應用程序都是經 過數字證書簽名的,數字證書的私鑰則保存在程序開發者的手中。Android將數字證書用來標識應用程序的作者和在應用程序之間建立信任關系,不是用來決 定最終用戶可以安裝哪些應用程序。這個數字證書並不需要權威的數字證書簽名機構認證,它只是用來讓應用程序包自我認證的。
同一個開發者的多個程序盡可能使用同一個數字證書,這可以帶來以下好處。
(1)有利於程序升級,當新版程序和舊版程序的數字證書相同時,Android系統才會認為這兩個程序是同一個程序的不同版本。如果新版程序和舊版程序的數字證書不相同,則Android系統認為他們是不同的程序,並產生沖突,會要求新程序更改包名。
(2)有利於程序的模塊化設計和開發。Android系統允許擁有同一個數字簽名的程序運行在一個進程中,Android程序會將他們視為同一個程序。所以開發者可以將自己的程序分模塊開發,而用戶只需要在需要的時候下載適當的模塊。
(3) 可以通過權限(permission)的方式在多個程序間共享數據和代碼。Android提供了基於數字證書的權限賦予機制,應用程序可以和其他的程序共 享概功能或者數據給那那些與自己擁有相同數字證書的程序。如果某個權限(permission)的protectionLevel是signature, 則這個權限就只能授予那些跟該權限所在的包擁有同一個數字證書的程序。
在簽名時,需要考慮數字證書的有效期:
(1)數字證書的有效期要包含程序的預計生命周期,一旦數字證書失效,持有改數字證書的程序將不能正常升級。
(2)如果多個程序使用同一個數字證書,則該數字證書的有效期要包含所有程序的預計生命周期。
(3)Android Market強制要求所有應用程序數字證書的有效期要持續到2033年10月22日以后。
Android數字證書包含以下幾個要點:
(1)所有的應用程序都必須有數字證書,Android系統不會安裝一個沒有數字證書的應用程序
(2)Android程序包使用的數字證書可以是自簽名的,不需要一個權威的數字證書機構簽名認證
(3)如果要正式發布一個Android ,必須使用一個合適的私鑰生成的數字證書來給程序簽名,而不能使用adt插件或者ant工具生成的調試證書來發布。
(4)數字證書都是有有效期的,Android只是在應用程序安裝的時候才會檢查證書的有效期。如果程序已經安裝在系統中,即使證書過期也不會影響程序的正常功能。
(5)Android使用標准的java工具 Keytool and Jarsigner 來生成數字證書,並給應用程序包簽名。
(6)使用zipalign優化程序。
Android 系統不會安裝運行任何一款未經數字簽名的apk程序,無論是在模擬器上還是在實際的物理設備上。Android的開發工具(ADT插件和Ant)都可以協 助開發者給apk程序簽名,它們都有兩種模式:調試模式(debug mode)和發布模式(release mode)。
在調試模式下,android的開發工具會在每次編譯時使用調試用的數字證書給程序簽名,開發者無須關心。
當要發布程序時,開發者就需要使用自己的數字證書給apk包簽名,可以有兩種方法。
(1)在命令行下使用JDK中的和Keytool(用於生成數字證書)和Jarsigner(用於使用數字證書簽名)來給apk包簽名。
(2)使用ADT Export Wizard進行簽名(如果沒有數字證書可能需要生成數字證書)。
使用Keytool和Jarsigner給程序簽名
命令:keytool -genkey -v -keystore android.keystore -alias android -keyalg RSA -validity 20000
該 命令中,-keystore ophone.keystore 表示生成的證書,可以加上路徑(默認在用戶主目錄下);-alias ophone 表示證書的別名是ophone;-keyalg RSA 表示采用的RSA算法;-validity 20000表示證書的有效期是20000天。
此時,我們會在互用主目錄下看到ophone.keystore,即我們剛剛創建的證書。
接着對程序進行簽名:
jarsigner用法: [選項] jar 文件別名
jarsigner -verify [選項] jar 文件
執行:jarsigner -verbose -keystore android.keystore -signedjar android123_signed.apk android123.apk android 就可以生成簽名的apk文件,這里輸入文件android123.apk,最終生成android123_signed.apk為Android簽名后的 APK執行文件。下面提示輸入的密碼和keytool輸入的一樣就行了。(不過在我的JDK目錄下沒有找到jarsigner這個程序,不知道是怎么回 事)
使用ADT Export Wizard進行簽名
應用程序(apk)簽名,在EC中,右鍵單擊應用程序工程,如圖選擇
選擇證書的存放路徑,填寫相關資料,完成,即可生成被簽名的apk文件。如下圖所示:
如上圖所示,我們可以看到也可以在這里選擇”Create new keystore“來創建一個證書。輸入密碼,點擊下一步,填寫相關信息,如下圖所示。
使用zipalign優化APK
根據官方文檔的描述,Android系統中Application的數據都保存在它的APK文件中,同時可以被多個進程訪問,安裝的過程包括如下幾個步驟:
- Installer通過每個apk的manifest文件獲取與當前應用程序相關聯的permissions信息
- Home application讀取當前APK的Name和Icon等信息。
- System server將讀取一些與Application運行相關信息,例如:獲取和處理Application的notifications請求等。
- 最后,APK所包含的內容不僅限於當前Application所使用,而且可以被其它的Application調用,提高系統資源的可復用性。
zipalign 優化的最根本目的是幫助操作系統更高效率的根據請求索引資源,將resource-handling code統一將Data structure alignment(數 據結構對齊標准:DSA)限定為4-byte boundaries。如果不采取對齊的標 准,處理器無法准確和快速的在內存地址中定位相關資源。目前的系統中使用fallback mechanism機制處理那些沒有應用DSA標准的應用程序,這的確大大的方便了普通開發者無需關注繁瑣的內存操作問題。但是相反,對於這樣的應用程序 將給普通用戶帶來一定的麻煩,不但影響程序的運行的效率,而且使系統的整體執行效率下降和占用大量不必要的內存資源,甚至消耗一定的電池資源 (battery life)。
命令行方式手動優化:
- 利用tools文件夾下的zipalign工具。首先調出cmd命令行,然后執行:zipalign -v 4 source.apk androidres.apk。這個方法不受API Level的限制,可以對任何版本的APK執行Align優化。
- 同時可以利用zipalign工具檢查當前APK是否已經執行過Align優化。命令:zipalign -c -v 4 androidres.apk
使用ADT自動優化:
- 從 ADT 0.9.3版本開始,可以通過export wizard自動對發布的application packages執行align操作。設置方法:鼠標右鍵點擊Project,然后選擇”Android Tools” > “Export Signed Application Package…”。
如果你以前的程序是采用默認簽名的方式(debug簽名),一旦換了新的簽名應用將不能覆蓋安裝,必須將原先的程序卸載掉,才能安裝上。
因為程序覆蓋安裝主要檢查兩點:
1)兩個程序的入口Activity是否相同。兩個程序如果包名不一樣,即使其它所有代碼完全一樣,也不會被視為同一個程序的不同版本;
2)兩個程序所采用的簽名是否相同。如果兩個程序所采用的簽名不同,即使包名相同,也不會被視為同一個程序的不同版本,不能覆蓋安裝。
另外,可能有人可能會認為反正debug簽名的應用程序也能安裝使用,那也沒有必要自己簽名了嘛。千萬不要這樣想,debug簽名的應用程序有這樣兩個限制,或者說風險:
1)debug簽名的應用程序不能在Android Market上架銷售,它會強制你使用自己的簽名;
Debug模式下簽名用的證書(默認是Eclipse/ADT和Ant編譯)自從它創建之日起,1年后就會失效。
2)debug.keystore在不同的機器上所生成的可能都不一樣,就意味着如果你換了機器進行apk版本升級,那么將會出現上面那種 程序不能覆蓋安裝的問題。不要小視這個問題,如果你開發的程序只有你自己使用,當然無所謂,卸載再安裝就可以了。但要是你的軟件有很多使用客戶,這就是大 問題了,就相當於軟件不具備升級功能!
綜上所述,可以使用Keytool、Jarsigner、zipalign 給程序簽名並優化程序,這樣就需要三個不同的工具:
keytool -genkey -v -keystore android.keystore -alias android -keyalg RSA -validity 20000
jarsigner -verbose -keystore android.keystore -signedjar android123_signed.apk android123.apk android
zipalign -v 4 android123_signed.apk android123_signed_aligned.apk
當然,也可以通過ADT插件中Export Signed Application Package…來執行,圖形界面更為簡單、形象、直觀。
參考:http://blog.csdn.net/centralperk/article/details/7425593
blog.csdn.net/zgfee/archive/2009/11/11/4796831.aspx
Android SDK:androidappdocs.appspot.com/guide/publishing/app-signing.html
android123.com.cn/androidkaifa/173.html
yarin.javaeye.com/blog/549280
androidres.com/index.php/2009/10/18/use-zipalign-to-optimize-your-application-packages/