android應用程序的簽名 (Signature)

本文轉自作者:xy0811 http://xy0811.spaces.live.com ,很強大,謝謝共享。

 

1.          爲什麼要簽名

1)         發送者的身份認證
由於開發商可能通 過使用相同的 Package Name 來混淆替換已經安裝的程序,以此保證簽名不同的包不被替換

2)         保證信息傳輸的完整性
簽名對於包中的每 個文件進行處理,以此確保包中內容不被替換

3)         防止交易中的抵賴發生, Market 對軟件的要求

2.          簽名的說明

1)         所有的應用程序都必須有數字證書, Android 系統不會安裝一個沒有數字證書的應用程序

2)         Android 程序包使用的數字證書可以是自簽名的,不需要一個權威的數字證書 機構簽名認證

3)         如果要正式發佈一個 Android 應用,必須使用一個合適的私鑰生成的數字證書來給程序簽名,而不能使用 adt 插件或者 ant 工具生成的調試證書來發布

4)         數字證書都是有有效期的, Android 只是在應用程序安裝的時候纔會檢查證書的有效期。如果程序已經安裝在系統中,即使證書過期也不會影響程序的正 常功能

5)         簽名後需使用 zipalign 優化程序

6)         Android 將數字證書用來標識應用程序的作者和在應用程序之間建立信任關 系,而不是用來決定最終用戶可以安裝哪些應用程序

3.          簽名的方法

1)         eclipse 插件方式簽名

a)          調試簽名
eclipse
插件默認賦予程序一 個 DEBUG 權限的簽名,此簽名的程序不能發佈到 market 上,此簽名有效期爲一年,如果過期則導致你無法生成 apk 文件,此時你只要刪除 debug keystore 即可, 系統又會爲你生成有效期爲一年的新簽名

b)         開發者生成密鑰並簽名
右鍵點擊項目名, 在菜單中選擇 Android Tools ,然後選擇 Export Signed Application Package… ,即可通過 eclipse 自定義證書並簽名

c)          開發者導出未簽名的包
右鍵點擊項目名, 在菜單中選擇 Android Tools ,然後選擇 Export Signed Application Package… ,即可導出未簽名的包,之後可通過命令行方式簽名

2)         用命令行方式簽名
使用標準的 java 工具 keytool jarsigner 來生成證書和給程序簽名

a)          生成簽名
$ keytool -genkey -keystore keyfile -keyalg RSA -validity 10000 -alias yan
注: validity 爲天數, keyfile 爲生成 key 存放的文件, yan 爲私鑰, RSA 爲指定的加密算法 ( 可用 RSA DSA)

b)         apk 文件簽名
$ jarsigner -verbose -keystore keyfile -signedjar signed.apk base.apk yan
注: keyfile 爲生成 key 存放的文件, signed.apk 爲簽名後的 apk base.apk    爲未籤 名的 apk yan 爲私鑰

c)          看某個 apk 是否經過了簽名
$ jarsigner -verify my_application.apk

d)         優化(簽名後需要做對齊優化處理)
$ zipalign -v 4 your_project_name-unaligned.apk your_project_name.apk

3)         在源碼中編譯的簽名

a)          使用源碼中的默認簽名
在源碼中編譯一般 都使用默認簽名的,在某源碼目錄中用運行
$ mm showcommands
能看到簽名命令
Android
提供了簽名的程序 signapk.jar ,用法如下:
$ signapk publickey.x509[.pem] privatekey.pk8 input.jar output.jar
*.x509.pem
x509 格式公鑰, pk8 爲私鑰
build/target/product/security
目錄中有四組默認籤 名可選: testkey, platform, shared, media (具體見 README.txt ),應用程序中 Android.mk 中有一個 LOCAL_CERTIFICATE 字段,由它指定用哪個 key 簽名,未指定的默認用 testkey.

b)         在源碼中自簽名
Android
提供了一個腳本 mkkey.sh build/target/product/security/mkkey.sh ),用於生成密鑰,生成後在應用程序中通過 Android.mk 中的 LOCAL_CERTIFICATE 字段指名用哪個簽名

c)          mkkey.sh 介紹

                                       i.              生成公鑰
openssl genrsa -3 -out testkey.pem 2048
其中 -3 是算法的參數, 2048 是密鑰長度, testkey.pem 是輸出的文件

                                      ii.              轉成 x509 格式(含作者有效期等)
openssl req -new -x509 -key testkey.pem -out testkey.x509.pem -days 10000 -subj ‘/C=US/ST=California/L=Mountain View/O=Android/OU=Android/CN=Android/[email protected]

                                    iii.              生成私鑰
openssl pkcs8 -in testkey.pem -topk8 -outform DER -out testkey.pk8 -nocrypt
把的格式轉換成 PKCS #8 ,這裏指定了 -nocryp ,表示不加密,所以簽名時不用輸入密碼

4.          簽名的相關文件

1)         apk 包中籤名相關的文件在 META_INF 目錄下
CERT.SF
:生成每個文件相對的密鑰
MANIFEST.MF
:數字簽名信息
xxx.SF
:這是 JAR 文件的簽名文件,佔位符 xxx 標識了簽名者
xxx.DSA
:對輸出文件的簽名和公鑰

2)         相關源碼
development/tools/jarutils/src/com.anroid.jarutils/SignedJarBuilder.java
frameworks/base/services/java/com/android/server/PackageManagerService.java
frameworks/base/core/java/android/content/pm/PackageManager.java
frameworks/base/cmds/pm/src/com/android/commands/pm/Pm.java
dalvik/libcore/security/src/main/java/java/security/Sign*
build/target/product/security/platform.*
build/tools/signapk/*

5.          簽名的相關問題
一般在安裝時提示 出錯: INSTALL_PARSE_FAILED_INCONSISTENT_CERTIFICATES

1)         兩個應用,名字相同,簽名不同

2)         升級時前一版本簽名,後一版本沒簽名

3)         升級時前一版本爲 DEBUG 簽名,後一個爲自定義簽名

4)         升級時前一版本爲 Android 源碼中的簽名,後一個爲 DEBUG 簽名或自定義簽名

5)         安裝未簽名的程序

6)         安裝升級已過有效期的程序

6.          相關工具

1)         查看某個 x509 證書的的有效日期
SignApk.java 中打印出 publicKey.getNotAfter() 即可

7.          參考
http://developer.android.com/guide/publishing/app-signing.html
http://www.pgcw.com.cn/Newsdetail.asp?id=257565010
http://www.eoeandroid.com/thread-23010-1-1.html
http://pepa.javaeye.com/blog/250991

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