在Android 系統中,所有安裝到系統的應用程式都必有一個數位憑證,此數位憑證用於標識應用程式的作者和在應用程式之間建立信任關係,如果一個 permission的protectionLevel為signature,那麼就只有那些跟該permission所在的程式擁有同一個數位憑證的應 用程式才能取得該許可權。Android使用Java的數位憑證相關的機制 來 給apk加蓋數位憑證,要理解android的數位憑證,需要先瞭解以下數位憑證的概念和java的數位憑證機制。Android系統要求每一個安裝進系 統的應用程式都是經過數位憑證簽名的,數位憑證的私密金鑰則儲存在程式開發人員的手中。Android將數位憑證用來標識應用程式的作者和在應用程式之間建立信 任關係,不是用來決定終端使用者可以安裝哪些應用程式。這個數位憑證並不需要權威的數位憑證簽名機構認證,它只是用來讓應用程式套件組合自我認證的。
在整個平台的安全性方面Google也使用了Android簽名機制,當然這裡使用Sun的針對Jar檔案簽名工具jarsigner即可,這裡我們需要瞭解一些問題,為什麼要簽名? 其實安裝到真機G1的軟體都必須簽名。
平時我們在Android Market上下載的軟體都必需簽名,所以說上傳時是免不了這個操作的,常規的簽名步驟可以查看 Android簽名用keytool和jarsigner製作apk檔案 這點Google設計的還好,沒有像Symbian那樣針對S60第三版和第五版都需要花費每次200美元的測試費用,如果遇到了ZipException invalid entry compressed size的錯誤方法過去我們在無法對jar進行簽名,Android jarsigner問題一文中提到了,主要原因是平時Eclipse使用的ADT外掛程式已經賦予了DEBUG許可權的數位簽章,我們可以通過匯出一個未簽名的APK檔案就可以解決,參考如何匯出一個未簽名的APK檔案?即可順利的簽名。
一、同一個開發人員的多個程式儘可能使用同一個數位憑證 ,這可以帶來以下好處。
(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給程式簽名( 用於1.5以下版本 )
命令:keytool -genkey -v -keystore android.keystore -alias android -keyalg RSA -validity 20000
該命令中,-keystore ophone.keystore 表示產生的認證,可以加上路徑(預設在使用者主目錄下);-alias ophone 表示認證的別名是ophone;-keyalg RSA 表示採用的RSA演算法;-validity 20000表示認證的有效期間是20000天。
Android程式的簽名和Symbian類似都可以自簽名(Self-signed),但是在Android平台中認證初期還顯得形同虛設,平時開發時通過ADB介面上傳的程式會自動被簽有Debug許可權的程式。需要簽名驗證在上傳程式到Android Market上時大家都已經發現這個問題了。Android signed製作方法
首先在Android開發時沒有安裝JDK的網友在Sun官方網站下載JDKhttp://www.java.net/download/jdk ... 6-p-12_sep_2008.exe,其實僅需要中的Keytool和Jarsigner。
詳細的簽名步驟:
第一步
C:\Program Files\Java\jdk1.6.0_10\bin>keytool -genkey -alias android123.keystore
-keyalg RSA -validity 20000 -keystore android123.keystore
輸入keystore密碼:[密碼不回顯]
再次輸入新密碼:[密碼不回顯]
您的名字與姓氏是什嗎?
[Unknown]: android123
您的組織單位名稱是什嗎?
[Unknown]: www.android123.com.cn
您的組織名稱是什嗎?
[Unknown]: www.android123.com.cn
您的組織名稱是什嗎?
[Unknown]: www.android123.com.cn
您所在的城市或地區名稱是什嗎?
[Unknown]: New York
您所在的州或省份名稱是什嗎?
[Unknown]: New York
該單位的兩字母國家代碼是什麼
[Unknown]: CN
CN=android123, OU=www.android123.com.cn, O=www.android123.com.cn, L=New York, ST
=New York, C=CN 正確嗎?
[否]: Y
輸入<android123.keystore>的主密碼
(如果和 keystore 密碼相同,按斷行符號):
其中參數-validity為認證有效天數,這裡我們寫的大些20000天。還有在輸入密碼時沒有回顯,只管輸入就可以了,一般位元建議使用20位,最後需要記下來後面還要用,整 個 過程:
接下來我們開始為apk檔案簽名了。
第二步
執行下面這句jarsigner -verbose -keystore android123.keystore -signedjar android123_signed.apk android123.apk android123.keystore 就可以生辰簽名的apk檔案,這裡輸入檔案android123.apk,最終產生android123_signed.apk為Android簽名後的 APK執行檔案。下面提示輸入的密碼和keytool輸入的一樣就行了
有關Android程式發布和簽名可以查看SDK中 http://code.google.com/android/devel/sign-publish.html 一文.
附上keytool參數以及jarsigner參數:
keytool用法:
-certreq [-v] [-protected]
[-alias <別名>] [-sigalg <sigalg>]
[-file <csr_file>] [-keypass <密鑰庫口令>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-changealias [-v] [-protected] -alias <別名> -destalias <目標別名>
[-keypass <密鑰庫口令>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-delete [-v] [-protected] -alias <別名>
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-exportcert [-v] [-rfc] [-protected]
[-alias <別名>] [-file <認證檔案>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-genkeypair [-v] [-protected]
[-alias <別名>]
[-keyalg <keyalg>] [-keysize <密鑰大小>]
[-sigalg <sigalg>] [-dname <dname>]
[-validity <valDays>] [-keypass <密鑰庫口令>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-genseckey [-v] [-protected]
[-alias <別名>] [-keypass <密鑰庫口令>]
[-keyalg <keyalg>] [-keysize <密鑰大小>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-help
-importcert [-v] [-noprompt] [-trustcacerts] [-protected]
[-alias <別名>]
[-file <認證檔案>] [-keypass <密鑰庫口令>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-importkeystore [-v]
[-srckeystore <源密鑰庫>] [-destkeystore <目標密鑰庫>]
[-srcstoretype <源儲存類型>] [-deststoretype <目標儲存類型>]
[-srcstorepass <源存放庫口令>] [-deststorepass <目標存放庫口令>]
[-srcprotected] [-destprotected]
[-srcprovidername <源提供方名稱>]
[-destprovidername <目標提供方名稱>]
[-srcalias <源別名> [-destalias <目標別名>]
[-srckeypass <源密鑰庫口令>] [-destkeypass <目標密鑰庫口令>]]
[-noprompt]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-keypasswd [-v] [-alias <別名>]
[-keypass <舊密鑰庫口令>] [-new <新密鑰庫口令>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-list [-v | -rfc] [-protected]
[-alias <別名>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
-printcert [-v] [-file <認證檔案>]
-storepasswd [-v] [-new <新存放庫口令>]
[-keystore <密鑰庫>] [-storepass <存放庫口令>]
[-storetype <儲存類型>] [-providername <名稱>]
[-providerclass <提供方類名稱> [-providerarg <參數>]] ...
[-providerpath <路徑列表>]
jarsigner用法: [選項] jar 檔案別名
jarsigner -verify [選項] jar 檔案
[-keystore <url>] 密鑰庫位置
[-storepass <口令>] 用於密鑰庫完整性的口令
[-storetype <類型>] 密鑰庫類型
[-keypass <口令>] 專用密鑰的口令(如果不同)
[-sigfile <檔案>] .SF/.DSA 檔案的名稱
[-signedjar <檔案>] 已簽名的 JAR 檔案的名稱
[-digestalg <演算法>] 摘要演算法的名稱
[-sigalg <演算法>] 簽名演算法的名稱
[-verify] 驗證已簽名的 JAR 檔案
[-verbose] 簽名/驗證時輸出詳細資料
[-certs] 輸出詳細資料和驗證時顯示認證
[-tsa <url>] 時間戳記機構的位置
[-tsacert <別名>] 時間戳記機構的公用密鑰認證
[-altsigner <類>] 替代的簽名機制的類名
[-altsignerpath <路徑列表>] 替代的簽名機制的位置
[-internalsf] 在簽名塊內包含 .SF 檔案
[-sectionsonly] 不計算整個清單的散列
[-protected] 密鑰庫已保護驗證路徑
[-providerName <名稱>] 提供者名稱
[-providerClass <類> Data Encryption Service提供者的名稱
[-providerArg <參數>]] ... 主類檔案和建構函式參數
此時,我們會在互用主目錄下看到ophone.keystore,即我們剛剛建立的認證。
第二種簽名方式:現在介紹android 1.5及更新版本的apk簽名方式
1、開啟Eclipse->選擇你要簽名的項目->右擊->android tools->Export signed Application package...
2、跳出視窗
3、project checks 如果核對項目名沒有問題的話 點擊 Next
然後跳出keystore selection 如果是已經存在keystore的檔案就選擇然後next 輸入keystore的密碼進行簽名。
如果沒有的話選擇 create new keystore 然後選擇 keystore 儲存的位置,設定keystore的密碼,點擊Next。
4、填寫keystore的基本資料,如,別名,密碼,有效期間,姓名,組織,組織名稱,所在城市,所在省份,國家等,點擊Next
5、選擇被簽名後的APK儲存位置。點擊finish。
6、就可以在你儲存的位置中找到相應的被簽名後的APK檔案。
以上的簽名只有在ANDROID1.5以及以後的版本適用。謝謝。
希望對大家有協助,謝謝。
Android簽名教程文檔下載:Android簽名教程