安卓apk簽名及相關工具(keytool、jarsigner 、zipalign)的使用

keytool

keytool工具 是一個Java 數據證書的管理工具,它是JDK自帶的一個在命令行下執行的程序。

常用命令:

genkey 生成密鑰對(公鑰和私鑰)
-v 顯示密鑰庫中的證書詳細信息
-alias <alias_name> 祕鑰的別名,只有前8個字符有效
-keyalg <alg> 生成祕鑰的算法,支持DSA和RSA
-keysize <size> 生成祕鑰的位數,默認1024位,建議使用2048以上的位數
-dname <name> 發佈者名稱,如未指定,在使用jarsigner簽名時會提示輸入
-keypass <password> 祕鑰的密碼
-validity <valDays> 密鑰的有效期是多少天
-storepass <password> keystore的密碼

如下是使用Keytool生成keystore文件,使用RSA算法,祕鑰長度爲4096位

    keytool -genkey -keystore my-release-key.keystore -alias my_alias -keyalg RSA -keysize 4096 -validity 10000 

生成的過程中會讓我們填寫一些信息,如密碼、城市等,生成的keystore文件默認在當前目錄下。


jarsigner

Android系統中的簽名算法使用MD5作爲哈希算法並使用RSA進行加密和解密,計算apk的哈希算法使用SHA-1

常用命令:

-keystore <keystore-name>.keystore keystore路徑
-signedjar <signed-apk-name>.apk 簽名後apk文件輸出路徑
-verbose 輸出詳細信息
-sigalg <算法> 簽名算法
-digestalg <算法> 處理apk使用的哈希算法
-verify 驗證已簽名的jar文件

我們通過工具導出一個未經過簽名的apk文件,爲其簽名

  • 通過Eclipse:
    右鍵單擊項目名稱,選擇AndroidTools→Export Unsinged Application Package

  • 通過AndroidStudio
    在找到項目右側的Gradle按鈕,點擊打開
    在打開的窗口中找到項目名對應的Gradle,依次進入Tasks→build,點擊assemble進行生成
    生成後的apk文件在moudle的build/outputs/apk目錄下,文件名包含unsigned的apk文件即是生成的未簽名apk文件

jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore  -signedjar my_application_signed.apk my_application_unsigned.apk my_alias

如圖所示,雖然我們簽名成功了。但是會提示警告:

警告:
No -tsa or -tsacert is provided and this jar is not timestamped. Without a timestamp, users may not be able to validate this jar after the signer certificate's expiration date (2045-10-02) or after any future revocation date.

大概意思是說,未提供 -tsa 或 -tsacert, 此 jar 沒有時間戳。如果沒有時間戳, 則在簽名者證書的到期或以後的任何撤銷日期之後,用戶可能無法驗證此jar。

解決此問題的方法就是在命令後面添加時間戳網址,完整命令如下:

jarsigner -sigalg MD5withRSA -digestalg SHA1 -keystore my-release-key.keystore  -signedjar my_application_signed.apk my_application_unsigned.apk my_alias -tsa http://sha256timestamp.ws.symantec.com/sha256/timestamp 

網上大部分讓加的-tsa https://timestamp.geotrust.com/tsa 會提示無法對 jar 進行簽名: 時間戳頒發機構沒有響應。
原因是這個時間戳網址已經過期了

我們可以通過如下命令進行驗證簽名是否成功:

jarsigner -verify my_application_signed.apk

如果你使用的是一個簽過名的apk文件,執行重簽名會報如下錯誤:

jarsigner: 無法對 jar 進行簽名: java.util.zip.ZipException: invalid entry compressed size
如果有重簽名(與之前簽名不同)的需求,可以把要重簽名的apk後綴改成zip,打開後刪除裏面的META-INF目錄,然後重新改成apk後綴,再次進行簽名


zipalign

簽名之後,我們還可以使用zipalign工具對安裝包進行對齊優化,這樣能夠讓應用程序和整個系統運行得更快

開發工具進行zipalign非常方便:

  • Eclipse中的ADT插件(0.9.3及以上版本)可以自動zipalign對齊:
    右鍵單擊項目名稱,選擇AndroidTools→Export Signed Application Package

  • Android studio在build.gradle文件中加入zipAlignEnabled true 開啓zipalign對齊:

    buildTypes {
        release {
            ...
            zipAlignEnabled true
            ...
        }
    }
  • 手動zipalign對齊:
    Android 1.6及以後的SDK的 build-tools/版本/ 文件夾下都有zipalign工具。例如我的路徑是:

C:\Users\hanpeng\AppData\Local\Android\Sdk\build-tools\23.0.1\zipalign.exe

在簽名後使用以下命令進行zipalign對齊:

zipalign -v 4 my_application_signed.apk my_application_signed_zipaligned.apk

對齊驗證:

zipalign -c -v 4 my_application_signed_zipaligned.apk

參考:
《Android安全機制解析與應用實踐》 第八章 Android應用安全實用解決方案

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