Apk簽名,每一個Android開發者都不陌生。它就是對我們的apk加了一個校驗參數,防止apk被掉包。一開始做Android開發,就接觸到了apk簽名;后來在微信開放平台、高德地圖等平台注冊時,需要填寫apk簽名的md5值和sha256值;再后來做系統應用,接觸到了系統簽名;而后就想了解下apk的生成機制,學習了如何用命令行進行簽名。很早時以為很簡單的簽名,真沒想到也蘊含這么豐富的知識,就想整理一下,也分享給其它小伙伴們。
文章結構:
- 利用Android Studio生成簽名與對apk進行簽名
- 獲取簽名文件的md5值和sha256值
- 獲取系統簽名
- 利用命令行生成簽名與對apk進行簽名
一、利用Android Studio生成簽名與對apk進行簽名
利用Android Studio(或者Eclipse)生成簽名與對apk進行簽名,是最常用的簽名方式。本文也就從這里開始說起。
1.生成簽名
依次選擇Build——Generate Signed Bundle/APK——選擇apk——點擊Next,會看到Key store path下面有兩個按鈕(如圖1)。
我們這里是要生成簽名,當然選擇Create New…,打開New Key Store對話框(如圖2),填入指定的信息后,點擊OK即可生成簽名。
2.對apk進行簽名
打開Generate Signed Bundle or APK對話框后,直接選擇已有的簽名即可,點擊Next,選擇輸出路徑、簽名版本后,點擊Finish即可生成簽名后的版本。
3.Android Studio2.2之后的V1簽名和V2簽名
當使用Android Studio2.2及以后版本進行簽名打包時,會發現多了一個對簽名版本的選擇(如圖3),這個V1和V2表示什么意思呢?
V1就是傳統的簽名方式,V2則是Android7.0之后引入的。其區別是,V1是通過ZIP條目進行驗證,這樣APK 簽署后可進行許多修改;而V2驗證壓縮文件的所有字節,而不是單個 ZIP 條目,這樣在簽名后無法再更改。V2的好處很明顯,更安全且驗證更迅速。所以,推薦在生成apk時,簽名方式選擇V1+V2。當然,僅僅選擇V1也是可以的。如果僅選擇V2呢,這樣生成的apk在Android7.0及之后的版本上沒有問題,不過會導致7.0以下的版本無法安裝,所以要避免這種方式。
4.在gradle中配置簽名信息
我們都知道Android使用gradle來構建版本,因此我們也希望在gradle中配置好簽名信息,在打包apk時更方便。
在項目的build.gradle中,android下加入signingConfig信息。
1 |
signingConfigs { |
5.jks與keystore
從Eclipse開始做Android開發的小伙伴都知道,Eclipse默認生成的簽名文件是keystore格式,而Android Studio生成的是jks格式。二者只是簽名格式的不同,是可以進行轉換的(如何轉換,后續會專門介紹)。
二、獲取簽名文件的md5值和sha256值
在文章開始時,就提到了在許多開放平台注冊時,需要用到apk簽名的md5值和sha256值,怎么獲取呢?這里提供了兩種方法。
1.用命令行獲取md5值和sha256值
1 |
keytool -v -list -keystore hyydev.jks |
如圖4。
2.用代碼獲取md5值和sha256值
除了用keytool命令獲取外,也可以通過代碼獲取簽名的md5值和sha256值。
代碼如下:
1 |
public static String getSign(Context context, String packageName) { |
三、獲取系統簽名
Android系統的簽名信息不是keystore或jks格式,它默認存在buildtargetproductsecurity目錄下(如圖5)。如果需要獲取系統簽名的信息,需要在Ubuntu環境下把它轉換為keystore或jks格式。
1.生成keystore簽名文件
1>.取platform.pk8 platform.x509.pem放到一個目錄下
2>.生成platform.pem
1 |
openssl pkcs8 -in platform.pk8 -inform DER -outform PEM -out platform.pem -nocrypt |
3>.生成platform.p12
1 |
openssl pkcs12 -export -in platform.x509.pem -inkey platform.pem -out platform.pk12 -name dev |
4>.生成hyysign.keystore
1 |
keytool -importkeystore -deststorepass android -destkeypass hyydev -destkeystore hyysign.keystore -srckeystore platform.pk12 -srcstoretype PKCS12 -srcstorepass hyydev -alias dev |
2.生成jks簽名文件
與生成keystore文件類似。
1>.取platform.pk8 platform.x509.pem放到一個目錄下
2>.生成platform.pem文件
1 |
openssl pkcs8 -inform DER -nocrypt -in platform.pk8 -out platform.pem |
3>.生成platform.p12
1 |
openssl pkcs12 -export -in platform.x509.pem -out platform.p12 -inkey platform.pem -password pass:hyydev -name hyy |
4>.生成hyysign.jks
1 |
keytool -importkeystore -deststorepass hyydev -destkeystore hyysign.jks -srckeystore platform.p12 -srcstoretype PKCS12 -srcstorepass hyydev |
3.哪些apk的簽名必須使用系統簽名文件
有些apk需要系統權限,比如實現關機指令。
如何聲明系統權限呢?
在AndroidMainfest.xml的mainfest中加入:
1 |
android:sharedUserId="android.uid.system" |
用到系統權限的apk,起簽名必須使用系統簽名,否則安裝不上,會報錯誤(如圖6)。
四、利用命令行生成簽名與對apk進行簽名
上面所提到的簽名,都是利用IDE來生成簽名、進行簽名,用命令行該怎么做呢?
1.生成簽名
1 |
keytool -genkeypair -alias hyydev -keyalg RSA -validity 400 -keystore hyydev.keystore |
2.對未簽名的apk進行簽名
1 |
jarsigner -verbose -keystore hyydev.keystore -signedjar TestSign.apk Test.apk hyydev |
3.重簽名
進行重簽名時,會報錯java.util.zip.ZipException: invalid entry compressed size (expected 41278 but got 42575bytes) bytes)。如何解決呢?就是要重簽名的apk后綴改成zip,打開后刪除里面的META-INF目錄,然后重新改成apk后綴,再進行簽名就可以了。