Google 致力于为黑人社区推动种族平等。查看具体举措
本頁面由 Cloud Translation API 翻譯而成。
Switch to English

APK簽名方案v3

Android 9支持APK密鑰旋轉,這使應用程序能夠在APK更新中更改其簽名密鑰。為了使輪換切實可行,APK必須指示新的和舊的簽名密鑰之間的信任級別。為了支持密鑰旋轉,我們將APK簽名方案從v2更新到了v3,以允許使用新密鑰和舊密鑰。 V3將有關受支持的SDK版本和旋轉證明結構的信息添加到APK簽名塊。

APK簽名塊

為了保持與v1 APK格式的向後兼容性,v2和v3 APK簽名存儲在緊鄰ZIP中央目錄之前的APK簽名塊中。

v3 APK簽名塊格式與v2相同。 APK的v3簽名存儲為ID值對,其ID為0xf05368c0。

APK簽名方案v3塊

v3方案被設計為與v2方案非常相似。它具有相同的通用格式,並支持相同的簽名算法ID ,密鑰大小和EC曲線。

但是,v3方案添加了有關受支持的SDK版本和旋轉證明結構的信息。

格式

APK簽名方案v3塊存儲在APK簽名塊中,其ID為0xf05368c0

APK簽名方案v3塊的格式遵循v2的格式:

  • 長度前綴signer的長度前綴序列:
    • 長度前綴的signed data
      • 長度前綴digests的長度前綴序列:
        • signature algorithm ID (4個字節)
        • digest (長度前綴)
      • X.509 certificates長度前綴序列:
        • 長度前綴的X.509 certificate (ASN.1 DER格式)
      • minSDK (uint32)-如果平台版本低於此數字,則應忽略此簽名者。
      • maxSDK (uint32)-如果平台版本高於此數字,則應忽略此簽名者。
      • 帶有長度前綴的additional attributes的長度前綴序列:
        • ID (uint32)
        • value (可變長度:附加屬性的長度-4個字節)
        • ID - 0x3ba06f8c
        • value -旋轉證明結構
    • minSDK (uint32)-簽名數據部分中minSDK值的副本-用於在當前平台不在範圍內時跳過對此簽名的驗證。必須匹配簽名數據值。
    • maxSDK (uint32)-簽名數據部分中maxSDK值的副本-用於在當前平台不在範圍內時跳過對此簽名的驗證。必須匹配簽名的數據值。
    • 長度signatures序列的長度前綴序列:
      • signature algorithm ID (uint32)
      • 長度超過signed data signature
    • 長度前綴的public key (SubjectPublicKeyInfo,ASN.1 DER形式)

旋轉證明和值得信賴的舊證書結構

輪換證明結構允許應用旋轉其簽名證書,而不會在與其通信的其他應用上被阻止。為此,應用程序簽名包含兩個新數據:

  • 向第三方斷言,無論其前任產品在哪裡受信任,均可信任該應用程序的簽名證書
  • 應用本身仍然信任的較舊的簽名證書

“簽名數據”部分中的“旋轉證明”屬性由一個單鏈接列表組成,每個節點包含一個用於對應用程序的先前版本進行簽名的簽名證書。此屬性旨在包含概念上的旋轉證明和可信賴的舊證書數據結構。該列表按版本排序,具有與根節點相對應的最早的簽名證書。通過使每個節點中的證書在列表中的下一個簽名,並因此為每個新密鑰賦予證據以證明它應與舊密鑰一樣受信任,來構建旋轉證明數據結構。

自我信任的舊證書數據結構是通過向每個節點添加標誌以指示其成員資格和屬性的集合來構造的。例如,可以存在一個標誌,指示在給定節點上的簽名證書受信任以獲取Android簽名權限。此標誌允許仍然使用舊證書籤名的其他應用授予使用新簽名證書籤名的應用定義的簽名權限。由於整個旋轉證明屬性位於v3 signer字段的簽署數據部分中,因此該屬性受到用於對包含的apk進行簽名的密鑰的保護。

這種格式排除了多個簽名密鑰以及將不同的祖先簽名證書收斂到一個(多個起始節點到一個公共接收器)的可能性。

格式

旋轉證明存儲在APK簽名方案v3塊內,其ID為0x3ba06f8c 。其格式為:

  • 長度前綴levels的長度前綴序列:
    • 長度signed data (由以前的證書(如果存在))
      • 長度前綴的X.509 certificate (ASN.1 DER格式)
      • signature algorithm ID (uint32)-上一級證書使用的算法
    • flags (uint32)-標誌,用於指示此證書是否應位於自信任舊證書結構中以及對其進行的操作。
    • signature algorithm ID (uint32)-必須與下一級的“簽名數據”部分的signature algorithm ID匹配。
    • 以上signed data長度前綴signature

多個證書

Android當前將使用多個證書籤名的APK視為具有唯一的簽名身份(與包含的證書分開)的APK。因此,簽名數據部分中的旋轉證明屬性形成有向無環圖,可以更好地將其視為單鏈接列表,給定版本的每組簽名者代表一個節點。這為旋轉證明結構(下面的多標誌版本)增加了額外的複雜性。特別地,訂購成為一個問題。而且,不再可以單獨對APK進行簽名,因為旋轉證明結構必須具有舊的簽名證書來簽名新的證書集,而不是一個個地對其進行簽名。例如,由密鑰A簽名的,希望由兩個新密鑰B和C簽名的APK不能讓B簽名者僅包括A或B的簽名,因為這是與B和C不同的簽名身份。意味著簽名者必須在建立這樣的結構之前進行協調。

多個簽署者旋轉證明屬性

  • 長度前綴sets的長度前綴序列:
    • signed data (按先前設置-如果存在)
      • certificates長度前綴序列
        • 長度前綴的X.509 certificate (ASN.1 DER格式)
      • signature algorithm IDs序列(uint32)-上一組證書中每個證書的signature algorithm IDs序列相同。
    • flags (uint32)-標誌,用於指示此證書集是否應在“可信任的舊證書”結構中以及進行哪些操作。
    • 長度signatures序列的長度前綴序列:
      • signature algorithm ID (uint32)-必須與簽名數據部分中的一個匹配
      • 以上signed data長度前綴signature

旋轉證明結構中的多個祖先

v3方案也無法處理將兩個不同的密鑰旋轉為同一應用程序使用的相同簽名密鑰。這與收購的情況不同,在收購的情況下,收購公司希望移動所收購的應用程序以使用其簽名密鑰來共享權限。此次收購被視為受支持的用例,因為新應用將通過其程序包名稱加以區分,並且可以包含其自己的旋轉證明結構。相同應用程序具有兩種到達同一證書的不同路徑的不受支持的情況打破了密鑰輪換設計中的許多假設。

驗證

在Android 9及更高版本中,可以根據APK簽名方案v3,v2方案或v1方案來驗證APK。較舊的平台會忽略v3簽名,並嘗試先驗證v2簽名,然後再驗證v1。

APK簽名驗證過程

圖1. APK簽名驗證過程

APK簽名方案v3驗證

  1. 找到APK簽名塊並驗證:
    1. APK簽名塊的兩個大小字段包含相同的值。
    2. ZIP中央目錄後緊跟中央目錄記錄的ZIP結束。
    3. 中央目錄的ZIP末尾沒有更多數據。
  2. 在APK簽名塊中找到第一個APK簽名方案v3塊。如果存在v3塊,請繼續執行步驟3。否則,請退回到使用v2方案驗證APK。
  3. 對於APK簽名方案v3塊中具有最低和最高SDK版本(位於當前平台範圍內)的每個signer
    1. signatures選擇最受支持的signature algorithm ID 。強度排序取決於每個實現/平台版本。
    2. 驗證相應的signaturesignatures反對signed data使用public key 。 (現在可以安全地分析signed data 。)
    3. 驗證簽名數據中的最小和最大SDK版本是否與為signer指定的版本相匹配。
    4. 驗證digestssignatures中籤名算法ID的排序列表是否相同。 (這是為了防止簽名剝離/添加。)
    5. 使用與簽名算法使用的摘要算法相同的摘要算法計算APK內容的摘要。
    6. 驗證所計算的摘要是等同於相應的digestdigests
    7. 驗證第一的是SubjectPublicKeyInfo進行certificatecertificates是相同的public key
    8. 如果signer存在旋轉證明屬性,請驗證該結構有效,並且該signer是列表中的最後一個證書。
  4. 如果在當前平台的範圍內僅找到一個signer則驗證成功,並且該signer步驟3成功。

驗證方式

要測試您的設備是否正確支持v3​​,請在cts/hostsidetests/appsecurity/src/android/appsecurity/cts/運行PkgInstallSignatureVerificationTest.java CTS測試。