淺入淺出Android安全:第六章Android安全的其它話題

apachecn_飛龍發表於2016-12-02

第六章 Android 安全的其它話題

來源:Yury Zhauniarovich | Publications

譯者:飛龍

協議:CC BY-NC-SA 4.0

在本章中,我們會涉及到與 Android 安全相關的其他主題,這些主題不直接屬於已經涉及的任何主題。

6.1 Android 簽名過程

Android 應用程式以 Android 應用包檔案(.apk檔案)的形式分發到裝置上。 由於這個平臺的程式主要是用 Java 編寫的,所以這種格式與 Java 包的格式 – jar(Java Archive)有很多共同點,它用於將程式碼,資源和後設資料(來自可選的META-INF目錄 )檔案使用 zip 歸檔演算法轉換成一個檔案。 META-INF目錄儲存軟體包和擴充套件配置資料,包括安全性,版本控制,擴充套件和服務[5]。 基本上,在 Android 的情況中,apkbuilder工具將構建的專案檔案壓縮到一起[1],使用標準的 Java 工具jarsigner對這個歸檔檔案簽名[6]。 在應用程式簽名過程中,jarsigner建立META-INF目錄,在 Android 中通常包含以下檔案:清單檔案(MANIFEST.MF),簽名檔案(副檔名為.SF)和簽名塊檔案(.RSA.DSA) 。

清單檔案(MANIFEST.MF)由主屬性部分和每個條目屬性組成,每個包含在未簽名的apk中檔案擁有一個條目。 這些每個條目中的屬性儲存檔名稱資訊,以及使用 base64 格式編碼的檔案內容摘要。 在 Android 上,SHA1 演算法用於計算摘要。 清單 6.1 中提供了清單檔案的摘錄。

1 Manifest−Version : 1.0 
2 Created−By: 1.6.0 41 (Sun Microsystems Inc. ) 
3 
4 Name: res/layout/main . xml 
5 SHA1−Digest : NJ1YLN3mBEKTPibVXbFO8eRCAr8= 
6 
7 Name: AndroidManifest . xml 
8 SHA1−Digest : wBoSXxhOQ2LR/pJY7Bczu1sWLy4=

程式碼 6.1:清單檔案的摘錄

包含被簽名資料的簽名檔案(.SF)的內容類似於MANIFEST.MF的內容。 這個檔案的一個例子如清單 6.2 所示。 主要部分包含清單檔案的主要屬性的摘要(SHA1-Digest-Manifest-Main-Attributes)和內容摘要(SHA1-Digest-Manifest)。 每個條目包含清單檔案中的條目的摘要以及相應的檔名。

 1 Signature−Version : 1.0 
 2 SHA1−Digest−Manifest−Main−Attributes : nl/DtR972nRpjey6ocvNKvmjvw8= 
 3 Created−By: 1.6.0 41 (Sun Microsystems Inc. ) 
 4 SHA1−Digest−Manifest : Ej5guqx3DYaOLOm3Kh89ddgEJW4= 
 5 
 6 Name: res/layout/main.xml 
 7 SHA1−Digest : Z871jZHrhRKHDaGf2K4p4fKgztk= 
 8 
 9 Name: AndroidManifest.xml 
10 SHA1−Digest : hQtlGk+tKFLSXufjNaTwd9qd4Cw= 
11 ...

程式碼 6.2:簽名檔案的摘錄

最後一部分是簽名塊檔案(.DSA.RSA)。 這個二進位制檔案包含簽名檔案的簽名版本; 它與相應的.SF檔案具有相同的名稱。 根據所使用的演算法(RSA 或 DSA),它有不同的副檔名。

相同的apk檔案有可能簽署幾個不同的證照。 在這種情況下,在META-INF目錄中將有幾個.SF.DSA.RSA檔案(它們的數量將等於應用程式簽名的次數)。

6.1.1 Android 中的應用簽名檢查

大多數 Android 應用程式都使用開發人員簽名的證照(注意 Android 的“證照”和“簽名”可以互換使用)。 此證照用於確保原始應用程式的程式碼及其更新來自同一位置,並在同一開發人員的應用程式之間建立信任關係。 為了執行這個檢查,Android 只是比較證照的二進位制表示,它用於簽署一個應用程式及其更新(第一種情況)和協作應用程式(第二種情況)。

這種對證照的檢查通過PackageManagerService中的方法int compareSignatures(Signature[] s1,Signature[] s2)來實現,程式碼如清單 6.3 所示。在上一節中,我們注意到在 Android 中,可以使用多個不同的證照籤署相同的應用程式。這解釋了為什麼該方法使用兩個簽名陣列作為引數。儘管該方法在 Android 安全規定中佔有重要地位,但其行為強烈依賴於平臺的版本。在較新版本中(從 Android 2.2 開始),此方法比較兩個Signature陣列,如果兩個陣列不等於null,並且如果所有s2簽名都包含在s1中,則返回SIGNATURE MATCH值,否則為SIGNATURE_NOT_MATCH。在版本 2.2 之前,此方法檢查陣列s1是否包含在s2中。這種行為允許系統安裝升級,即使它們已經使用原始應用程式的證照子集簽名[2]。

在幾種情況下,需要同一開發人員的應用程式之間的信任關係。 第一種情況與signaturesignatureOrSystem的許可權相關。 要使用受這些許可權保護的功能,宣告許可權和請求它的包必須使用同一組證照籤名。 第二種情況與 Android 執行具有相同 UID 或甚至在相同 Linux 程式中執行不同應用程式的能力有關。 在這種情況下,請求此類行為的應用程式必須使用相同的簽名進行簽名。

 1 static int compareSignatures ( Signature[] s1 , Signature[] s2 ) { 
 2   if ( s1 == null ) { 
 3     return s2 == null 
 4       ? PackageManager.SIGNATURE_NEITHER_SIGNED 
 5       : PackageManager.SIGNATURE_FIRST_NOT_SIGNED; 
 6   } 
 7   if ( s2 == null ) { 
 8     return PackageManager.SIGNATURE_SECOND_NOT_SIGNED; 
 9   } 
10   HashSet<Signature> set1 = new HashSet<Signature>() ; 
11   for ( Signature sig : s1 ) { 
12     set1.add( sig ) ; 
13   } 
14   HashSet<Signature> set2 = new HashSet<Signature>() ; 
15   for ( Signature sig : s2 ) { 
16     set2.add( sig ) ; 
17   } 
18   // Make sure s2 contains all signatures in s1 . 
19   if ( set1.equals ( set2 ) ) { 
20     return PackageManager.SIGNATURE_MATCH; 
21   } 
22   return PackageManager.SIGNATURE_NO_MATCH; 
23 }

程式碼 6.3:PackageManagerService中的compareSignatures方法


相關文章