1. 程式人生 > >Android 7.0APK簽名新方案-APK signature scheme v2

Android 7.0APK簽名新方案-APK signature scheme v2

證書和金鑰庫

公鑰證書(也稱為數字證書或身份證書)包含公鑰/私鑰對的公鑰,以及可以標識金鑰所有者的一些其他元資料(例如名稱和位置)。證書的所有者持有對應的私鑰。

在您簽署 APK 時,簽署工具會將公鑰證書附加到 APK。公鑰證書充當“指紋”,用於將 APK 唯一關聯到您及您的對應私鑰。這有助於 Android 確保您 APK 的任何將來更新都是原版更新並來自原始作者。

金鑰庫是一種包含一個或多個私鑰的二進位制檔案。在您使用 Android Studio 簽署要釋出的 APK 時,您可以選擇生成新的金鑰庫和私鑰,或者使用您已經擁有的金鑰庫和私鑰。您應當為金鑰庫選擇一個強密碼,併為金鑰庫中儲存的每個私鑰選擇一個單獨的強密碼。您必須將金鑰庫存放在安全可靠的地方。請參閱下面的

保護您的私鑰部分。

您必須在應用的整個生命週期內使用相同的證書,以便使用者能夠以應用更新的形式安裝新版本。要詳細瞭解為所有應用在其整個生命週期內使用相同證書的好處,請參閱下面的簽署注意事項

簽署您的除錯構建

從 IDE 中執行或除錯您的專案時,Android Studio 將自動使用通過 Android SDK 工具生成的除錯證書籤署您的 APK。當您在 Android Studio 中首次執行或除錯專案時,IDE 將自動在 $HOME/.android/debug.keystore 中建立除錯金鑰庫和證書,並設定金鑰庫和金鑰密碼。

由於除錯證書通過構建工具建立並且在設計上不安全,大多數應用商店(包括 Google Play 商店)都不接受使用除錯證書籤署要釋出的 APK。

Android Studio 會自動將您的除錯簽署資訊儲存在簽署配置中,因此您不必在每次除錯時都輸入此資訊。簽署配置是一種包含簽署 APK 所需全部必要資訊的物件,這些資訊包括金鑰庫位置、金鑰庫密碼、金鑰名稱和金鑰密碼。您無法直接編輯除錯簽署配置,不過可以配置如何簽署您的釋出構建

如需瞭解有關如何針對除錯構建和執行應用的詳細資訊,請參閱構建和執行您的應用

除錯證書的有效期

用於針對除錯簽署 APK 的自簽署證書的有效期為 365 天,從其建立日期算起。當此證書到期時,您將收到一個構建錯誤。

要修復此問題,只需刪除 debug.keystore 檔案即可。檔案儲存在以下位置:

  • ~/.android/
    (OS X 和 Linux)
  • C:\Documents and Settings\<user>\.android\ (Windows XP)
  • C:\Users\<user>\.android\(Windows Vista,Windows 7、8 和 10)

當您下次構建和執行除錯構建型別時,這些構建工具將重新生成新的金鑰庫和除錯金鑰。請注意,您必須執行應用,單純的構建不會重新生成金鑰庫和除錯金鑰。

簽署您的釋出構建

您可以使用 Android Studio 手動生成簽署的 APK,既可以一次生成一個 APK,也可以一次為多個構建變體生成 APK。除了手動簽署 APK 外,您還可以將 Gradle 構建設定配置為在構建流程期間自動處理簽署。本部分將介紹手動簽署流程。要詳細瞭解如何在構建流程中籤署應用,請參閱配置構建流程以自動簽署您的 APK

要在 Android Studio 中手動簽署用於釋出的 APK,請按以下步驟操作:

  1. 在選單欄中,點選 Build > Generate Signed APK
  2. 從下拉選單中選擇您想要釋出的模組,然後點選 Next
  3. 如果您已經擁有金鑰庫,請轉到第 5 步。如果您希望建立一個新的金鑰庫,請點選 Create new

  4. 在 New Key Store 視窗上,為您的金鑰庫和金鑰提供以下資訊,如圖 1 所示。

    圖 1. 在 Android Studio 中建立新的金鑰庫。

    金鑰庫

    • Key store path:選擇建立金鑰庫的位置。
    • Password:為您的金鑰庫建立並確認一個安全的密碼。

    金鑰

    • Alias:為您的金鑰輸入一個標識名。
    • Password:為您的金鑰建立並確認一個安全的密碼。此密碼應當與您為金鑰庫選擇的密碼不同
    • Validity (years):以年為單位設定金鑰的有效時長。金鑰的有效期應至少為 25 年,以便您可以在應用的整個生命期內使用相同的金鑰簽署應用更新。
    • Certificate:為證書輸入一些關於您自己的資訊。此資訊不會顯示在應用中,但會作為 APK 的一部分包含在您的證書中。

    填寫完表單後,請點選 OK

  5. 在 Generate Signed APK Wizard 視窗上,選擇一個金鑰庫和一個私鑰,併為它們輸入密碼。(如果您已經在上一步中建立金鑰庫,這些欄位將自動填充。)然後,點選 Next

    圖 2. 在 Android Studio 中選擇一個私鑰。

  6. 在下一個視窗上,為簽署的 APK 選擇一個目的地、選擇構建型別、選擇產品風味(如果適用),然後點選 Finish

    圖 3. 為已選擇的產品風味生成簽署的 APK。

    :如果您的專案使用多個產品風味,那麼在 Windows/Linux 上按住 Ctrl 鍵或者在 Mac OS X 上按住 Command 鍵可以選擇多個產品風味。Android Studio 將為選擇的每個產品風味生成單獨的 APK。

在流程完成後,您會在上面選擇的目標資料夾中找到簽署的 APK。現在,您可以通過像 Google Play 商店一樣的應用市場或者您選擇的機制分發簽署的 APK。要詳細瞭解如何將簽署的 APK 釋出到 Google Play 商店,請參閱開始釋出。要詳細瞭解其他分發選項,請閱讀替代分發選項

為了確保使用者將更新成功安裝到您的應用中,您需要在應用的整個生命週期內使用相同的證書籤署 APK。要詳細瞭解使用相同金鑰簽署所有應用的各種好處,請參閱下面的簽署注意事項。如需瞭解有關保護您的私鑰和金鑰庫的詳細資訊,請參閱保護您的私鑰

配置構建流程以自動簽署您的 APK

在 Android Studio 中,您可以建立一個簽署配置並將其分配至您的釋出構建型別,將您的專案配置為在構建流程中自動簽署釋出 APK。一個簽署配置包含一個金鑰庫位置、金鑰庫密碼、金鑰別名和金鑰密碼。要使用 Android Studio 建立一個簽署配置並將其分配至您的釋出構建型別,請按以下步驟操作:

  1. 在 Project 視窗中,右鍵點選您的應用並點選 Open Module Settings
  2. 在 Project Structure 視窗左面板中的 Modules 下,點選您想要簽署的模組。
  3. 點選 Signing 標籤,然後點選 Add 
  4. 選擇您的金鑰庫檔案,為此簽署配置輸入一個名稱(因為您可能建立多個配置),然後輸入所需的資訊。

    圖 4. 用於建立新簽署配置的視窗。

  5. 點選 Build Types 標籤。
  6. 點選 release 構建。
  7. 在 Signing Config 下,選擇您剛建立的簽署配置。

    圖 5. 在 Android Studio 中選擇一個簽署配置。

  8. 點選 OK

現在,在您每一次使用 Android Studio 構建釋出構建時,IDE 都會使用您指定的簽署配置自動簽署 APK。您可以在所構建模組專案目錄內部的 build/outputs/apk/ 資料夾中找到簽署的 APK。

在您建立簽署配置時,您的簽署資訊將以純文字形式包含到 Gradle 構建檔案中。如果您是團隊協作開發或者公開分享自己的程式碼,那麼您應當從構建檔案中移除簽署資訊並將其單獨儲存,從而確保此資訊的安全。要詳細瞭解如何從構建檔案中移除您的簽署資訊,請參閱從您的構建檔案中移除簽署資訊。要詳細瞭解如何保證簽署資訊保安,請參閱保護您的私鑰

以不同方式簽署每個產品風味

如果您的應用使用多個產品風味並且您想要以不同方式簽署每個風味,則可以建立更多簽署配置並將其按風味分配:

  1. 在 Project 視窗中,右鍵點選您的應用並點選 Open Module Settings
  2. 在 Project Structure 視窗左面板中的 Modules 下,點選您想要簽署的模組。
  3. 點選 Signing 標籤,然後點選 Add 
  4. 選擇您的金鑰庫檔案,為此簽署配置輸入一個名稱(因為您可能建立多個配置),然後輸入所需的資訊。

    圖 6. 用於建立新簽署配置的視窗。

  5. 如果需要,請重複第 3 步和第 4 步,直到您完成所有簽署配置的建立。
  6. 點選 Flavors 標籤。
  7. 點選您想要配置的風味,然後從 Signing Config 下拉選單中選擇合適的簽署配置。

    圖 7. 按產品風味配置簽署設定。

    重複操作以配置任何其他產品風味。

  8. 點選 OK

您還可以在 Gradle 配置檔案中指定您的簽署設定。如需瞭解詳細資訊,請參閱配置簽署設定

簽署 Android Wear 應用

釋出 Android Wear APK 時,請將可穿戴式裝置 APK 打包到手持類 APK 中,因為使用者無法直接在可穿戴式裝置上瀏覽和安裝應用。兩種 APK 都必須簽署。如需瞭解有關打包和簽署 Android Wear APK 的詳細資訊,請參閱打包可穿戴式裝置應用

簽署注意事項

在應用的預期生命週期內,您應使用相同證書籤署所有 APK。這麼做的原因有多個:

  • 應用升級:當系統安裝應用的更新時,它會比較新版本和現有版本中的證書。如果證書匹配,則系統允許更新。如果您使用不同的證書籤署新版本,則必須為應用分配另一個軟體包名稱 - 在此情況下,使用者將新版本作為全新應用安裝。
  • 應用模組化:Android 允許通過相同證書籤署的多個 APK 在同一個程序中執行(如果應用請求這樣),以便系統將它們視為單個應用。通過此方式,您可以在模組中部署您的應用,且使用者可以獨立更新每個模組。
  • 通過許可權共享程式碼/資料:Android 提供基於簽名的許可權執行,以便應用可以將功能展示給使用指定證書籤署的另一應用。通過使用同一個證書籤署多個 APK 並使用基於簽名的許可權檢查功能,您的應用可採用安全的方式共享程式碼和資料。

如果您計劃支援升級應用,請確保金鑰的有效期超出該應用的預期生命週期。建議有效期為 25 年或以上。當金鑰有效期過期後,使用者將不能再無縫升級到應用的新版本。

如果您計劃在 Google Play 上釋出您的應用,您用於簽署這些 APK 的金鑰的有效期必須在 2033 年 10 月 22 日以後結束。Google Play 強制執行此要求,以確保在新版本可用時,使用者可以無縫升級應用。

保護您的私鑰

維護您私鑰的安全性對於您和使用者來說都至關重要。如果您允許某人使用您的金鑰,或者將您的金鑰庫和密碼放在了不安全的地方,以致於第三方可以找到和使用它們,則會損害您的作者身份和使用者對您的信任。

如果某個第三方在您不知情或未經授權的情況下設法取得您的金鑰,此人可能會簽署和分發應用,從而惡意替換您的原版應用或損壞它們。另外,此人還可能利用您的身份簽署和分發應用,從而攻擊其他應用或系統本身,損壞或竊取使用者資料。

您應用的所有將來版本簽署時都需要使用您的私鑰。如果您的金鑰丟失或存放不當,您將無法釋出您的現有應用的更新。您無法重新生成以前生成的金鑰。

您作為開發者實體的聲譽取決於您能否每時每刻正確保護私鑰,直至金鑰過期。以下是針對保護金鑰安全的一些提示:

  • 為金鑰庫和金鑰選擇強密碼。
  • 請勿將您的私鑰贈與或借給任何人,也不要讓未經授權的人員知道您的金鑰庫和金鑰密碼。
  • 將包含私鑰的金鑰庫檔案存放在安全可靠的地方。

通常情況下,只要您在生成、使用和儲存金鑰時遵循通用的注意事項,就可以保障金鑰的安全。

從您的構建檔案中移除簽署資訊

在您建立簽署配置時,Android Studio 會以純文字形式將您的簽署資訊新增到模組的 build.gradle 檔案中。如果您是團隊協作開發或者將您的程式碼開源,那麼您應當將此敏感資訊從構建檔案中移出,以免被其他人輕易獲取。為此,您應建立一個單獨的屬性檔案來儲存安全資訊並按以下步驟操作,在您的構建檔案中引用該檔案:

  1. 建立一個簽署配置,並將其分配至一個或多個構建型別。這些說明假設您已經按照上面配置構建流程以自動簽署您的 APK 部分所述,為釋出構建型別配置了一個簽署配置。
  2. 在專案的根目錄下建立一個名稱為 keystore.properties 的檔案。此檔案應當包含您的簽署資訊,如下所示:
    storePassword=myStorePassword
    keyPassword=mykeyPassword
    keyAlias=myKeyAlias
    storeFile=myStoreFileLocation
  3. 在模組的 build.gradle 檔案中,於 android {} 塊的前面新增用於載入 keystore.properties 檔案的程式碼。
    ...// Create a variable called keystorePropertiesFile, and initialize it to your// keystore.properties file, in the rootProject folder.def keystorePropertiesFile = rootProject.file("keystore.properties")// Initialize a new Properties() object called keystoreProperties.def keystoreProperties =newProperties()// Load your keystore.properties file into the keystoreProperties object.
    keystoreProperties.load(newFileInputStream(keystorePropertiesFile))
    
    android {...}

    :您可以選擇將 keystore.properties 檔案儲存在其他位置(例如,儲存在模組資料夾中而不是專案的根資料夾中,或者如果您使用連續整合工具,也可以儲存在構建伺服器上)。在這種情況下,您應當修改上面的程式碼,以便使用實際 keystore.properties 檔案的位置正確初始化 keystorePropertiesFile

  4. 您可以使用語法 keystoreProperties['屬性名稱'] 引用儲存在 keystoreProperties 中的屬性。修改模組 build.gradle 檔案的 signingConfigs 塊,以便使用此語法引用儲存在 keystoreProperties 中的簽署資訊。
    android {
        signingConfigs {
            config {
                keyAlias keystoreProperties['keyAlias']
                keyPassword keystoreProperties['keyPassword']
                storeFile file(keystoreProperties['storeFile'])
                storePassword keystoreProperties['storePassword']}}...}
  5. 開啟 Build Variants 工具視窗並確保已選擇釋出構建型別。
  6. 點選 Build > Build APK 以構建您的釋出構建,並確認 Android Studio 已在模組的 build/outputs/apk/ 目錄中建立一個簽署的 APK。

由於您的構建檔案不再包含敏感資訊,您現在可以將其包含在源控制中或者上傳到共享的程式碼庫。務必保證 keystore.properties 檔案的安全。您可能需要將其從您的源控制系統中移除。

手動簽署您的應用

不需要 Android Studio 也可以簽署您的應用。您可以通過 Android SDK 和 JDK 使用標準工具從命令列簽署您的應用。要通過命令列在釋出模式下籤署應用,請按順序完成以下步驟:

  1. 使用  生成一個私鑰。例如:

    $ keytool -genkey -v -keystore my-release-key.jks
    -keyalg RSA -keysize 2048 -validity 10000 -alias app
    

    本示例會提示您輸入金鑰庫和金鑰的密碼,併為您的金鑰提供“Distinguished Name”欄位。隨後,它將生成一個名為 my-release-key.jks 的金鑰庫檔案。此金鑰庫包含一個有效期為 10,000 天的金鑰。

  2. 在釋出模式下編譯您的應用,以獲取一個未簽署且未優化的 APK。

  3. 使用  優化未簽署的 APK:

    $ zipalign -v -p 4 my-app-unaligned.apk my-app.apk
    

    zipalign 可以確保所有未壓縮的資料均是以相對於檔案開始部分的特定位元組對齊開始,這樣可減少應用消耗的 RAM 量。

  4. 通過 apksigner 使用您的私鑰簽署 APK:

    $ apksigner sign --ks my-release-key.jks my-app.apk
    

    本示例使用單金鑰金鑰庫檔案 my-release-key.jks 中儲存的私鑰和證書籤署應用 my-app.apk

    apksigner 工具支援其他簽署選項,包括使用單獨的私鑰和證書檔案簽署 APK 檔案和使用多個簽署人簽署 APK。如需瞭解更多詳情,請參閱 apksigner 參考。

  5. 驗證您的 APK 是否已簽署:

    $ apksigner verify my-app.apk