這里重點介紹的是利用jdk中的兩個工具對Android的應用程序包apk文件進行簽名。
主要分為3個步驟:第一步生成簽名文件,第二步對apk文件簽名,第三步驗證簽名。
以下是執行命令,注意此段命令所生成的簽名文件和apk文件在同一目錄下。
首先進入dos命令行,運行-->cmd --> cd apk所在的路徑(以下簡稱apk_dir)
第一步生成簽名文件
apk_dir>keytool -genkey -keystore hellos.keystore -alias
hello -keyalg RSA -validity 2000
輸入keystore密碼:1q1q1q
再次輸入新密碼:1q1q1q
您的名字與姓氏是什么?
[Unknown]: jiezzy
您的組織單位名稱是什么?
[Unknown]: home
您的組織名稱是什么?
[Unknown]: person
您所在的城市或區域名稱是什么?
[Unknown]: Shanghai
您所在的州或省份名稱是什么?
[Unknown]: Shanghai
該單位的兩字母國家代碼是什么
[Unknown]: cn
CN=mark, OU=markorg, O=markorg, L=Shanghai, ST=Shanghai, C=cn 正確嗎?
[否]: Y
輸入的主密碼
(如果和 keystore 密碼相同,按回車):
再次輸入新密碼:
-----------------------------------------------------------------
以上命令執行完成在apk_dir目錄中將生成一個名字為hellos.keystore的簽名文件
第二步對apk文件簽名
apk_dir>jarsigner -verbose -keystore hellos.keystore -signe
djar hello_sig.apk helloworld.apk hello
輸入密鑰庫的口令短語:
正在添加: META-INF/HELLO.SF
正在添加: META-INF/HELLO.RSA
正在簽名: res/layout/linearlayout.xml
正在簽名: res/layout/main.xml
正在簽名: res/layout/progressbar.xml
正在簽名: res/layout/radio.xml
正在簽名: res/layout/relativelayout.xml
正在簽名: res/layout/tablelayout.xml
正在簽名: res/layout/user.xml
正在簽名: AndroidManifest.xml
正在簽名: resources.arsc
正在簽名: res/drawable-hdpi/icon.png
正在簽名: res/drawable-ldpi/icon.png
正在簽名: res/drawable-mdpi/icon.png
正在簽名: classes.dex
第三步驗證簽名
apk_dir>jarsigner -verify helloworld.apk
jar 已驗證。
另外一種方法是通過eclipse差距ADT工具生成,這里也簡單介紹一下:
第一步:選中你的android項目,點鼠標右鍵
Android Tools --> Export Signed Application Packge...
第二步
Project Checks(這里基本不用動) --> Keystore selection 選擇 create new keystore
在下面依次填寫簽名文件的名字(要以.store結尾),密碼,重復密碼 --> key creation
填寫簽名詳細信息
第三步
給簽名后的apk文件輸入一個名字,點Finsh完成!
1APK打包的步驟
首先,我們需要一個keystore,當然已經有了的話就不用這一步了:
cmd下:
進入到jdk的bin目錄,這樣的話,android.keystore文件就會生成在這個目錄下,簽名的時候我們需要這個文件
C:\Program Files\Java\jdk1.6.0_10\bin>keytool -genkey -alias android.keystore -keyalg RSA -validity 20000 -keystore android.keystore
輸入keystore密碼:
再次輸入新密碼:
您的名字與姓氏是什么?
[Unknown]: Mickle您的組織單位名稱是什么?
[Unknown]: www.ioou.com
您的組織名稱是什么?
[Unknown]: www.ioou.com
您所在的城市或區域名稱是什么?
[Unknown]: Shanghai
您所在的州或省份名稱是什么?
[Unknown]: Shanghai
該單位的兩字母國家代碼是什么
[Unknown]: CN
CN=Mickle, OU=www.ioou.com, O=www.ioou.com, L=Shanghai, ST=Shanghai, C=CN 正確嗎?
[否]: Y
輸入<android.keystore>的主密碼(如果和 keystore 密碼相同,按回車):其中參數-validity為證書有效天數,這里我們寫的大些10000天。還有在輸入密碼時沒有回顯(盡管輸就是啦) 並且 退格,tab等都屬於密碼內容,這個密碼在給.apk文件簽名的時候需要.
然后簽名:
Eclipse中,右擊需要簽名的工程-->android tools-->export signed application package...
出現下面對話框,選擇需要簽名的工程next,選擇上面生成的android.keystore文件位置和設置的密碼
next
next,選擇簽名生成文件的位置和名稱
finish,搞定啦..
2. 設置打包的APK文件的圖標和名稱
修改AndroidManifest.xml文件:
<application android:icon="@drawable/fruit" android:label="@string/app_name">
icon: 對應着你打包后顯示的快捷菜單的圖標
主Intent的label字符對應你的程序名稱
3.查看創建的信息
keytool -list -v -keysotre d:\app_key\alan_test(文件名) -storepass 123456
4.簽名之后,用zipalign(壓縮對齊)優化你的APK文件。
未簽名的apk不能使用,也不能優化。簽名之后的apk谷歌推薦使用zipalign.exe(位於android-sdk-windows ools目錄下)工具對其優化:
D:>zipalign -v 4 demo_signed.apk final.apk
如上,zipalign能夠使apk文件中未壓縮的數據在4個字節邊界上對齊(4個字節是一個性能很好的值),這樣android系統就可以使用mmap()(請自行查閱這個函數的用途)函數讀取文件,可以在讀取資源上獲得較高的性能,
PS:1.在4個字節邊界上對齊的意思就是,一般來說,是指編譯器吧4個字節作為一個單位來進行讀取的結果,這樣的話,CPU能夠對變量進行高效、快速的訪問(較之前不對齊)。
2.對齊的根源:android系統中的Davlik虛擬機使用自己專有的格式DEX,DEX的結構是緊湊的,為了讓運行時的性能更好,可以進一步用"對齊"進一步優化,但是大小一般會有所增加。
5.簽名對你的App的影響。
你不可能只做一個APP,你可能有一個宏偉的戰略工程,想要在生活,服務,游戲,系統各個領域都想插足的話,你不可能只做一個APP,谷歌建議你把你所有的APP都使用同一個簽名證書。
使用你自己的同一個簽名證書,就沒有人能夠覆蓋你的應用程序,即使包名相同,所以影響有:
1) App升級。 使用相同簽名的升級軟件可以正常覆蓋老版本的軟件,否則系統比較發現新版本的簽名證書和老版本的簽名證書不一致,不會允許新版本安裝成功的。
2) App模塊化。android系統允許具有相同的App運行在同一個進程中,如果運行在同一個進程中,則他們相當於同一個App,但是你可以單獨對他們升級更新,這是一種App級別的模塊化思路。
3) 允許代碼和數據共享。android中提供了一個基於簽名的Permission標簽。通過允許的設置,我們可以實現對不同App之間的訪問和共享,如下:
- AndroidManifest.xml:<permission android:protectionLevel="normal" />
- AndroidManifest.xml:<permission android:protectionLevel="normal" />
其中protectionLevel標簽有4種值:normal(缺省 值),dangerous, signature,signatureOrSystem。簡單來說,normal是低風險的,所有的App不能訪問和共享 此App。dangerous是高風險的,所有的App都能訪問和共享此App。signature是指具有相同簽名的App可以訪問和共享此App。 signatureOrSystem是指系統image中App和具有相同簽名的App可以訪問和共享此App,谷歌建議不要使用這個選項,因為簽名就足 夠了,一般這個許可會被用在在一個image中需要共享一些特定的功能的情況下。
7. 使用jarsigner工具為Android應用程序簽名
jarsigner -verbose -keystore liufeng.keystore -signedjar notepad_signed.apk notepad.apk liufeng.keystore
說明:
1)jarsigner是工具名稱,-verbose表示將簽名過程中的詳細信息打印出來,顯示在dos窗口中;
2)-keystore liufeng.keystore 表示簽名所使用的數字證書所在位置,這里沒有寫路徑,表示在當前目錄下;
3)-signedjar notepad_signed.apk notepad.apk 表示給notepad.apk文件簽名,簽名后的文件名稱為notepad_signed.apk;
4)最后面的liufeng.keystore 表示證書的別名,對應於生成數字證書時-alias參數后面的名稱
8. 使用zipalign工具優化已簽名的apk(非必須但建議這么做)
zipalign -v 4 notepad_signed.apk notepad_signed_aligned.apk
說明:
1)zipalign是工具名稱,-v表示在DOS窗口打印出詳細的優化信息;
2)notepad_signed.apk notepad_signed_aligned.apk 表示對已簽名文件notepad_signed.apk進行優化,優化后的文件名為 notepad_signed_aligned.apk
如果你以前的程序是采用默認簽名的方式(debug簽名),一旦換了新的簽名應用將不能覆蓋安裝,必須將原先的程序卸載掉,才能安裝上。
因為程序覆蓋安裝主要檢查兩點:
1)兩個程序的入口Activity是否相同。兩個程序如果包名不一樣,即使其它所有代碼完全一樣,也不會被視為同一個程序的不同版本;
2)兩個程序所采用的簽名是否相同。如果兩個程序所采用的簽名不同,即使包名相同,也不會被視為同一個程序的不同版本,不能覆蓋安裝。
另外,可能有人可能會認為反正debug簽名的應用程序也能安裝使用,那也沒有必要自己簽名了嘛。千萬不要這樣想,debug簽名的應用程序有這樣兩個限制,或者說風險:
1)debug簽名的應用程序不能在Android Market上架銷售,它會強制你使用自己的簽名;
Debug模式下簽名用的證書(默認是Eclipse/ADT和Ant編譯)自從它創建之日起,1年后就會失效。
2)debug.keystore在不同的機器上所生成的可能都不一樣,就意味着如果你換了機器進行apk版本升級,那么將會出現上面那種 程序不能覆蓋安裝的問題。不要小視這個問題,如果你開發的程序只有你自己使用,當然無所謂,卸載再安裝就可以了。但要是你的軟件有很多使用客戶,這就是大 問題了,就相當於軟件不具備升級功能!
一個android項目開發完成之后要安裝到設備上或者放到電子市場的話需要簽名認證. 下面就詳細簡介android簽名認證的過程及常見問題的解決.
1. 搭建java環境, 安裝並配置jdk
2. 安裝完成之后進行下列操作(本人jdk安裝目錄:D:\Program Files\Java\jdk1.6.0_18 )
2.1 生成keystore文件. 首先進入D:\Program Files\Java\jdk1.6.0_18\bin目錄 (這目錄下有兩個文件: keytool.exe , jarsigner.exe . 簽名就需要用到這兩個工具)
如果環境配置好的話,執行命令:
keytool -genkey -v -keystore crack.keystore -alias android -keyalg RSA -validity 20000
(原文)出現的問題1:
完成之后. 但是在D:\Program Files\Java\jdk1.6.0_18\bin目錄下始終找不到crack.keystore , 后來我將keystore文件保存指定目錄.
本人發現在 C:\Documents and Settings\Administrator中
2.2 簽名認證: 生成完keystore文件之后, 進行簽名認證執行如下命令:
jarsigner -verbose -keystore crack.keystore -signedjar CrackMe_signed.apk CrackMe.apk crack.keystore
出現問題2:
執行該命令之后總是報錯: jarsigner: 找不到 crack.keystore 的證書鏈。crack.keystore 必須引用包 含專用密鑰和相應的公共密鑰證書鏈的有效密鑰庫密鑰條目。
檢查后發現: 步驟2.1中 keystore文件名與別名不一致造成, 故將步驟2.1指令更改如下:
keytool -genkey -v -keystore crack.keystore -alias crack.keystore -keyalg RSA -validity 20000 , 再執行步驟2.2就OK啦.
在對android APK進行簽名的過程中,我碰到過幾種不同的問題:
問題一:jarsigner: 無法打開 jar 文件: ChangeBackgroundWidget.apk
我的解決方法是:將要進行簽名的APK放到對應的文件下,如我把要簽名的ChangeBackgroundWidget.apk放到JDK的bin文件里。
問題二:jarsigner: 找不到 androidapp.keystore 的證書鏈。androidapp.keystore 必須引用包含專用密鑰和相應的公共密鑰證書鏈的有效密鑰庫密鑰條目。
方法:在用keytool生成數字證書時必須保證:-keystore androidapp.keystore -alias androidapp.keystore 兩者名稱必須相同。
問題三:jarsigner: 無法對 jar 進行簽名: java.util.zip.ZipException: invalid entry comp
ressed size (expected 768 but got 800bytes)
這個問題,我還沒解決,在網上搜了下,找到了一種方法,但我實踐沒完全,所以不知道這個解決方法是否正確:
方法一:Android開發網提示這些問題主要是由於資源文件造成的,對於android開發來說應該檢查res文件夾中的文件,逐個排查。這個問題可以通過升級系統的JDK和JRE版本來解決。
方法二:這是因為默認給apk做了debug 簽名,所以無法做新的簽名這時就必須點工程右鍵->Android Tools ->Export Unsigned Application Package.
或者從AndroidManifest.xml的 Exporting上也是一樣的
然后再基於這個導出的unsigned apk做簽名,導出的時候最好將其目錄選在你之前產生keystore的那個目錄下,這樣操作起來就方便了。
