android應用程序簽名(轉)

android應用程序簽名(轉)

概述

Android系統要求,所有的程序經過數字簽名後才能安裝。Android系統使用這個證書來識別應用程序的作者,並且建立程序間的信任關係。證書不是用於用戶控制哪些程序可以安裝。證書不需要授權中心來簽名:Android應用程序上使用自己簽名的證書是完全允許且普遍的。

理解Android應用程序簽名有以下幾個重要點:

  • 所有的應用程序都必須簽名。系統不會安裝任何一個不簽名的程序。
  • 你可以使用自己的證書來簽名。不需要任何授權中心。
  • 當你要爲最終用戶發佈你的應用程序的時候,你必須簽入一個合適的密鑰。你不可以發佈程序的時候還使用SDK工具簽入的Debug Key。
  • 系統只在安裝應用程序的時候檢測證書的有效期。如果應用程序在安裝之後證書失效了,那麼,應用程序還是可以正常工作。
  • 你可以使用標準工具——Keytool和Jarsigner——生成Key並簽名apk文件。
  • 一旦你爲應用程序簽名了,一定要使用zipalign工具來優化最終的APK包。

Android系統不會安裝和運行沒有正確簽名的應用程序。這條規則適用於任何運行Android系統的地方,不管是真機還是模擬器。正是由於這個原因,你必須在模擬器或真機上運行/調試程序之前對程序進行簽名。

當你調試應用程序時,Android SDK工具替你對應用程序進行了簽名。Eclipse的ADT插件和Ant編譯工具都提供了兩種簽名模式——Debug模式和Release模式。

  • 當開發和測試時,你可以使用Debug模式。在Debug模式下,編譯工具使用內嵌在JDK中的Keytool工具來創建一個keystore和一個key(包含公認的名字和密碼)。在每次編譯的時候,使用這個Debug Key來爲apk文件簽名。由於密碼是公認的,在每次編譯的時候,也不需要提示你輸入keystore和key密碼。
  • 當你的程序準備發佈時,你必須在Release模式下,使用密鑰來爲apk文件簽名。有以下兩種方式可以做到:

o    命令行中使用Keytool和Jarsigner。在這個方法中,首先需要編譯出一個未簽名的apk。然後使用Jarsigner(或相似的工具),用你的密鑰爲apk手動簽名。如果你沒有合適的密鑰,你可以運行Keytool來手動生成自己的keystore/key。

o    使用ADT導出嚮導。如果你使用Eclipse/ADT插件進行開發,你可以使用導出嚮導來編譯程序,生成密鑰(如果需要),併爲apk簽名,所有這些操作都在導出嚮導中。一旦你的程序簽名了,別忘了運行zipalign來爲apk進行額外的優化。

簽名策略

應用程序簽名的某些方面可能會影響應用程序的開發,特別是你打算一起發佈多個應用程序的時候。

一般來說,推薦的策略是在整個應用程序壽命內,所有的程序簽上相同的證書。以下有幾個應該這麼做的原因:

  • 應用程序升級——當你對應用程序進行升級時,如果你想用戶平穩的升級,那麼,你就需要簽上相同的證書。當系統安裝一個升級應用程序時,如果新版本的證書與老版本的證書有匹配的話,那麼,系統纔會允許進行升級。如果你沒有爲版本簽上合適的證書,當你安裝時,你需要給應用程序指定一個新的包名——在這種情況下,用戶安裝的新版本,被當作是一個全新的應用程序。
  • 應用程序模塊化——如果應用程序請求的話,Android系統允許簽有相同證書的應用程序運行在相同的進程裏,這樣,系統就會把它們看作是一個單一的應用程序。用這種方法配置應用程序,用戶可以選擇更新每個獨立的模塊。
  • 代碼/數據權限共享——Android系統提供了基於簽名的權限檢查,因此,如果應用程序間簽有特定的證書,那麼,它們之間可以共享功能。通過多個程序簽有相同的證書並且使用基於簽名的權限檢查,你的程序可以以一種安全的方式共享代碼和數據。

還有一個決定簽名策略的重要因素是:如何設定key的有效期。

  • 如果你計劃支持單個應用程序的升級,你需要確保你的key擁有一個超過期望的應用程序生命週期的有效期。推薦使用25年或更多的有效期。當你的key過期了,用戶也就不能平穩的更新到新版本了。
  • 如果你想給多個無關的應用程序簽上相同的key,那麼,你必須確保key的有效期超過所有應用程序所有版本的生命週期,包括將來有可能添加到這一陣營的程序。
  • 如果你想在Android Market上發佈你的程序,key的有效期必須在2033.10.22以後。Market服務器強制這一要求,目前是保證用戶可以平穩的更新他們的程序。

當你設計應用程序時,一定要把這些點記在腦子裏,並且使用一個合適的證書來爲應用程序簽名。

簽名的基本設定

在你開始之前,你必須保證Keytool對SDK編譯工具來說是可利用的。多數情況下,你可以通過設置JAVA_HOME環境變量來告訴SDK編譯工具如何找到Keytool。另外,你還可以添加JDK中Keytool的路徑到PATH的變量裏。

如果你在Linux上開發,並且使用GNU編譯器來編譯Java,那麼,請確保系統是使用JDK中的Keytool,而不是gcj。如果Keytool已經在你的PATH中,它有可能是對/usr/bin/keytool的符號鏈接。在這種情況下,檢查符號鏈接的目標,確保它是指向JDK中的Keytool。

如果你打算對公衆釋放你的應用程序,你還需要Jarsigner工具。Jarsigner和Keytool都包含在JDK中。

Debug模式下簽名

Android編譯工具提供了Debug簽名模式,使得開發和調試應用程序更加容易,而且還滿足Android系統的簽名要求。當使用Debug模式編譯你的app時,SDK工具會調用Keytool工具自動創建一個Debug的keystore和key。然後,這個Debug key會自動用於apk的簽名,這樣,你不需要使用你自己的key來爲應用程序包簽名。

SDK工具使用預先定義好的名字/密碼來創建Debug keystore/key:

  • Keystore名字:“debug.keysotre”
  • Keystore密碼:“android”
  • Key別名:“androiddebugkey”
  • Key密碼:“android”
  • CN:“CN=Android Debug,O=Android,C=US”

如果需要的話,你可以改變Debug keystore/key的位置和名字,或者提供一個自定義的Debug keysotre/key。然而,任何自定義的Debug keystore/key必須使用和默認Debug key(上面描述的)相同的名字和密碼。(在Eclipse/ADT中,操作Windows>Preferences>Android>Build實現。)

注意: 你不能將簽有Debug證書的應用程序發佈給公衆。

 

Eclipse 用戶

如果你在Eclipse/ADT下開發(並且已經按照上面描述的“簽名的基本設定”配置了Keytool),Debug模式下簽名默認是開啓的。當你運行或是調試應用程序時,ADT會使用Debug證書進行簽名,並運行zipalign,然後安裝到選擇的模擬器或是連接上的設備。整個過程不需要你參與,前提是ADT能訪問Keytool。

Ant 用戶

如果你使用Ant來編譯你的apk文件,需要在ant命令中添加debug選項來開啓Debug簽名模式(假設你正在使用由android工具生成build.xml文件)。當你運行ant debug來編譯你的程序時,編譯腳本會生成一個keystore/key,併爲apk進行簽名。然後腳本會使用zipalign工具對apk進行對齊處理。整個過程不需要你參與。閱讀“其它IDE下開發:Debug模式編譯”來了解更多的信息。

Debug證書過期

Debug模式下簽名用的證書(默認是Eclipse/ADT和Ant編譯)自從它創建之日起,1年後就會失效。

當證書失效時,你會得到一個編譯錯誤,在Ant編譯上,錯誤如下:

debug:

[echo] Packaging bin/samples-debug.apk, and signing it with a debug key...

[exec] Debug Certificate expired on 8/4/08 3:43 PM

在Eclipse/ADT中,Android控制檯上你將會看到一個相似的錯誤。

爲了解決這個問題,只需要刪掉debug.keystore文件即可。AVD默認存儲的位置在:~/.android/avd(OS X和Linux),C:\Documents and Settings\\.android\(Windows XP),C:\Users\\.android\(Windows Vista)。

當下一次編譯的時候,編譯工具會重新生成一個新的keystore和Debug key。

Release模式下簽名

當你的程序準備好釋放給其它用戶時,你必須:

1.   獲取一個合適的密鑰

2.      在Release模式下編譯程序

3.      使用密鑰簽名程序

4.      對齊APK包

如果你是使用Eclipse/ADT插件開發,你可以使用導出嚮導來完成編譯、簽名和對齊等操作。在整個過程中,導出嚮導甚至還可以生成一個新的keystore和密鑰。因此,如果你使用Eclipse,你可以直接跳到“使用Eclipse ADT編譯和簽名”。

1. 獲取一個合適的密鑰

爲了進行程序的簽名,首先,你必須有一個合適的密鑰。密鑰指:

  • 個人持有。
  • 代表個人、公司或組織實體的身份。
  • 擁有一個有效期。有效期推薦超過25年。

如果你在Android Market上發佈你的程序,需要注意一點的是:程序的有效期需要在2033.10.22之後。你不能上傳一個應用程序,而它的key的有效期是在這個日期之前。

  • 不是由Android SDK工具生成的Debug key。

如果你沒有一個合適的key,你一定要使用Keytool來生成一個。如“基本設定”中描述的,確保Keytool可用。

爲了用Keytool生成一個key,使用keytool命令並傳入一些可選參數,如下表所示。

警告: 確保密鑰的安全。一定要閱讀“安全儲存你的密鑰”中討論如何確保你的密鑰的安全以及這對你和用戶爲何如此重要。尤其是,當你生成你的密鑰時,一定要爲keystore和key使用強密碼。

 

 

 

 

Keytool選項

描述

-genkey

生成一個鍵對(公鑰和密鑰)

-v

日誌輸出

-keystore <keystore-name>.keystore

命名包含密鑰的keystore

-storepass <password>

設定keystore的密碼。

基於安全考慮,不要在命令行中包含這一選項,除非你在一個安全的計算機上。如果你不提供,Keytool會提示你輸入。這樣,你的密碼就不會儲存在shell記錄中了。

-alias <alias_name>

設定key的別名

-keyalg <alg>

指定生成key時使用的加密算法。支持DSA和RSA。

-dname <name>

指定一個描述誰創建key的名字。該值將填入證書發行人的字段。

注意:你不需要在命令行中指明這些選項。如果不提供,Jarsigner會提示你輸入每個字段(CN,OU等)。

-validity <valdays>

Key的有效期,天數。

注意:推薦使用10000或更大的數。

-keypass <password>

Key的密碼。

基於安全考慮,不要在命令行中包含這一選項,除非你在一個安全的計算機上。如果你不提供,Keytool會提示你輸入。這樣,你的密碼就不會儲存在shell記錄中了。

下面是使用Keytool命令生成密鑰的例子:

$ keytool -genkey -v -keystore my-release-key.keystore 

-alias alias_name -keyalg RSA -validity 10000

運行上面的例子命令,Keytool會提示你輸入keystore和key的密碼,並且會提示你輸入key中其它的字段。然後,它會生成一個叫做my-release-key.keystore的文件。keystore和key受你輸入的密碼保護。keystore中包含一個key,有效期爲10000天。別名將在後面用到,在程序簽名時指當前這個keystore。

瞭解更多關於Keytool的信息,請參考http://java.sun.com/j2se/1.5.0/docs/tooldocs/#security

2. Release模式下編譯程序

爲了給用戶釋放程序,你必須在Release模式下編譯程序。在Release模式下,編譯程序不會進行默認簽名,並且你需要使用密鑰進行簽名。

注意: 你不能釋放未簽名的程序,或簽有Debug key的程序。

使用Eclipse

右擊Package Explorer中的工程,選擇Android Tools>Export Unsigned Application Package,導出一個未簽名的apk。然後指定未簽名apk的存儲位置。(另外,你也可以在Eclipse中打開AndroidManifest.xml文件,打開Manifest Tab,然後點擊Export an unsigned APK)。

注意:你也可以使用導出嚮導來完成編譯和簽名步驟,參考“使用Eclipse/ADT編譯和簽名”。

使用 Ant

如果你正在使用Ant,那麼你可以在ant命令中加入release選項來開啓Release模式。例如,如果你在包含build.xml文件的文件夾上運行Ant,命令可能看起來是這樣:

ant release

一般,編譯腳本在編譯apk的時候不會進行簽名。輸出的文件位於工程的bin/文件夾中,名爲<your_project_name>-unsigned.apk。由於apk文件還沒有簽名,所以你必須手動的使用密鑰進行簽名,然後使用zipalign進行對齊。

然而,Ant編譯腳本也可以替你執行簽名和對齊操作,前提是你在build.properties文件中提供了keystore的名字和key的別名。如果提供了這些信息,編譯腳本在執行ant release命令時會提示你輸入keystore和key的密碼,對包進行簽名並對齊。最後輸出的文件位於工程的bin/文件夾中,名爲<your_project_name>-release.apk。如果按照上述自動簽名和對齊操作執行,那麼,你就可以跳過下面的手動步驟(步驟3和4)。瞭解如何在build.properties文件中指定keystore和alias,請參考“其它IDE下開發:Release模式編譯”。

3. 使用密鑰簽名程序

如果你已經準備好要簽名的程序包的話,你可以使用Jarsigner工具進行簽名。如“基本設定”中描述的,請確保Jarsigner工具可用。此外,確保包含密鑰的keystore可用。

爲了簽名應用程序,你需要運行Jarsigner,並引用應用程序的apk及包含密鑰的keystore。下表列出了你可能使用的選項。

Jarsigner選項

描述

-keystore <keystore-name>.keystore

指定包含密鑰的keystore的名字

-verbose

日誌輸出

-storepass <password>

指定keystore的密碼。

基於安全考慮,不要在命令行中包含這一選項,除非你在一個安全的計算機上。如果你不提供,Jarsigner會提示你輸入。這樣,你的密碼就不會儲存在shell記錄中了

-keypass <password>

指定密鑰的密碼。

基於安全考慮,不要在命令行中包含這一選項,除非你在一個安全的計算機上。如果你不提供,Jarsigner會提示你輸入。這樣,你的密碼就不會儲存在shell記錄中了

下面是一個使用Jarsigner對my_application.apk進行簽名的例子,使用了上面創建的keystore。

$ jarsigner -verbose -keystore my-release-key.keystore 

my_application.apk alias_name

運行上面的示例命令,Jarsigner會提示你輸入keystore和key的密碼。然後它會修改apk文件,意味着apk文件現在已經簽上名了。注意:你可以使用不同的key對apk多次簽名。

檢驗apk文件是否簽名,可以使用下面的命令:

$ jarsigner -verify my_signed.apk

如果apk簽名正確,Jarsigner輸出“jar verified”。如果你想了解更多的細節,你可以嘗試這些命令:

$ jarsigner -verify -verbose my_application.apk

或者

$ jarsigner -verify -verbose -certs my_application.apk

上面的命令,添加-certs選項,將會顯示“CN=”行,描述誰創建了密鑰。

注意: 如果你看到“CN=Android Debug”,這意味apk文件使用Android SDK生成的Debug key籤的名。如果你想發佈你的程序,你必須使用自己的密鑰替換Debug key進行簽名。

瞭解更多Jarsigner的信息,請參考http://java.sun.com/j2se/1.5.0/docs/tooldocs/#security

4. 對齊APK

一旦你對apk文件使用密鑰進行簽名後,一定要運行zipalign進行對齊。這個工具能做到讓那些未壓縮的數據以特定的字節對齊。以4字節對齊能優化性能。當對齊後,Android系統能通過mmap()閱讀文件,即使它們包含二進制數據,而不是從包中拷貝所有的數據。好處是在運行程序時減少了隨機讀取內存的消耗。

zipalign由Android SDK提供,包含在tools/文件夾下。想對齊簽名後的apk,執行:

zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

-v標誌表示開始日誌輸出(可選)。4表示對齊的字節(不要使用非4的數字)。第一個文件參數是你的簽名後apk(輸入),第二個文件參數是目的apk文件(輸出)。如果你想覆蓋已經存在的apk,添加-f標誌。

注意: 在你使用zipalign優化包之前,輸入的apk必須是使用密鑰簽名後的。如果在zipalign操作之後再簽名,那麼對齊操作就白做了。

瞭解更多信息,請閱讀“zipalign”工具的文檔。

使用Eclipse/ADT編譯和簽名

如果你在使用Eclipse/ADT插件,你可以使用導出嚮導導出一個簽名的apk(甚至可以創建一個新的keystore,如果需要的話)。導出嚮導替你做了所有與Keytool和Jarsigner交互的工作,並且使用GUI來簽名應用程序,替代了上面提到的手動編譯、簽名和對齊的操作。一旦嚮導完成了編譯和簽名,也還會使用zipalign執行包的對齊操作。由於導出嚮導要使用Keytoo和Jarsigner。你應該確保它們是可用的,如“簽名的基本設定”中描述的那樣。

安全儲存你的密鑰

維護密鑰的安全是極其重要的。如果你讓其他人使用了你的key,或者你把keystore和密碼放在一個不安全的地方以至於第三方人員找到並使用了的話,那麼,你的授權認證和用戶的信任都將受到連累。

如果第三方沒有經過你的允許拿走了你的key,那個人就可以簽名併發布應用程序,並惡意替換或攻擊你的正版程序。這個人還可以簽名併發布應用程序,利用你的名義來攻擊其它程序或者系統自身,或者破壞、偷取用戶數據。

開發者的名聲依賴於正確的儲存你的密鑰,直到它過期。這裏有幾個安全儲存密鑰的提示:

  • 爲key和keystore設置強密碼。
  • 當你使用Keytool生成密鑰的時候,不要再命令行中添加-storepass和-keypass選項。如果你這樣做了,在shell記錄中就可以獲取你的密碼。
  • 相似的,當使用Jarsigner來簽名程序時,也不要在命令行中添加-storepass和-keypass選項。
  • 不要把密鑰給別人或借給別人,不要讓未授權的人知道你的keystore和key的密碼。

總而言之,只要你在生成、使用和儲存密鑰時有安全意識的話,它還是很安全的。 

 

 

 

xirihanlin 譯於2010.04.26

 

轉自: https://www.cnblogs.com/qq78292959/p/3772338.html

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章