一、應用安全基礎

作為目前兩大主流手機操作系統,Android和iOS已經牢牢的占據手機操作系統市場十余年。

Android是基于Linux內核的自由及開放源代碼的移動端操作系統。該系統最初由Andy Rubin開發,在2005年被美國的谷歌公司收購。2007年11月,谷歌與多家硬件制造商、軟件開發商及電信營運商組建開放手機聯盟共同研發改良Android系統。隨后谷歌以Apache開源許可證的授權方式,發布了Android的源代碼。

iOS是蘋果公司以Darwin(蘋果公司開發的一款UNIX操作系統)為基礎開發的一款移動端操作系統。不同于開源的Android系統,iOS系統選擇了封閉,只能用于蘋果旗下的iPad,iPhone,iPod touch等產品。

本章從App的簽名、安裝、權限、運行等幾個角度,分別對iOS與Android的App進行詳細介紹,并對比兩者區別。

1.1 應用的簽名

1.1.1 Android 簽名機制和原理

Android 系統要求所有 APK(Android application package,Android應用程序包)必須使用證書進行數字簽名,否則無法安裝或更新。在Android安裝或更新App時,系統首先檢驗App簽名,如果App未簽名或簽名校驗失敗,安裝操作將被拒絕。開發者可以自行為應用簽名并將其上傳到 Google Play 或其他應用商店,如果使用Android App Bundle格式在 Google Play 發布,則需將其上傳至Google Play 管理中心,使用Google Play提供的功能進行應用簽名。

簽名利用摘要和非對稱加密技術技術確保APK由開發者發布且未被篡改。摘要是使用哈希算法計算出的APK唯一的映射值,相當于APK的指紋,當APK文件內容發生任何改變時,摘要都會發生改變。簽名使用開發者的私鑰對摘要進行加密。用戶端安裝APK時,重新計算APK文件的摘要,然后使用開發者的公鑰解密簽名中的摘要,兩者對比一致則可說明APK來源可信且未被篡改。

Android 11及以前版本存在以下四種應用簽名方案:

◆v1:最基本的簽名方案,基于Jar的簽名

◆v2:提高驗證速度并增強完整性保證(Android 7.0 引入)

◆v3:支持密鑰輪替(Android 9.0 引入)

◆v4:根據APK的所有字節計算得出的Merkle哈希樹,需v2或v3簽名進行補充

備注:v4簽名是Google為解決增量安裝APK推出的功能,截至目前只能通過ADB安裝的方式使用。

Android簽名方案是向下兼容的。Android 7.0引入v2簽名,Android 9.0引入v3簽名,Android 11開始支持v4簽名,v4簽名需要v2或v3簽名進行補充,且簽名信息需要單獨的存儲在 .apk.idsig 文件中。Android系統優先選擇其所支持高版本簽名進行校驗,當不存在高版本簽名時則向下選擇。具體簽名校驗流程如下圖:

應用簽名工具

jarsigner是JDK提供的工具可以用于對jar簽名,apksigner是Google官方提供的用于Android 應用簽名和驗證的工具。無論是Android 應用的apk包還是jar包,本質都是zip格式的壓縮包,因此簽名流程相似。

jarsigner與apksigner的區別:

◆jarsigner:只能用于應用的v1簽名,簽名是只能使用keystore文件簽名;

◆apksigner:可以用于v1、v2、v3和v4簽名,簽名時即可以使用keystore文件進行簽名,還可以使用pem證書和私鑰進行簽名。

jarsigner簽名語法如下:

jarsigner -keystore keystore.jks -signedjar signed.apk unsigned.apk alias_name -storepass pwd

keystore.jks是簽名證書,signed.apk是簽名后的apk,unsigned.apk是待簽名的apk,alias_name是簽名證書的alias屬性,用來區分不同證書的,pwd是簽名證書的密碼。

apksigner簽名語法如下:

apksigner sign [signer_options] --ks keystore.jks | --key key.pk8 --cert cert.x509.pem --in unsigned_app.apk --out app-signed.apk

使用 --ks 選項指定密鑰庫文件。使用 --key 和 --cert 選項分別指定私鑰文件和證書文件。私鑰文件必須使用 PKCS #8 格式,證書文件必須使用 X.509 格式。如果signer_options未指定,默認情況下apksigner會根據應用中的 --min-sdk-version 和 --max-sdk-version 的值來決定使用哪種此簽名方案。

如果想禁用V2簽名

apksigner sign --v2-signing-enabled false --ks keystore.jks --in unsigned_app.apk --out app-signed.apk

如果想使用V3簽名

apksigner sign --v3-signing-enabled true --ks keystore.jks --in unsigned_app.apk --out app-signed.apk

創建應用簽名所需的證書文件

方案一:

使用Android Studio創建簽名文件Build > GenerateSignedBundle/APK > Apk > Next > Create new 根據提示設置文件生成路徑和訪問文件密碼,設置文件名和簽名密碼 , 設置國家城市信息等信息即可。

方案二:

使用命令行工具keytool生成簽名文件

keytool -genkeypair -alias test -keyalg RSA -keypass 123456 -keystore TestKey.jks -storepass 123456 -validity 3650

參數說明

證書文件內容查看:

keytool -list -v -keystore TestKey.jks -storepass 123456

應用完成簽名后應用中會新增 META-INF 文件夾,文件夾中包含如下三個文件:

具體簽名流程:

第一步,遍歷應用中的文件并計算文件對應的 SHA-1 摘要,將所的文件摘要進行 BASE64 編碼后寫入簽名文件即MANIFEST.MF 文件,具體MANIFEST.MF 文件示例內容下圖所示:

第二步,計算整個 MANIFEST.MF 文件的 SHA-1 摘要,進行 BASE64 編碼后寫入簽名文件,即.SF 文件;計算 MANIFEST.MF 文件中每一塊摘要的 SHA-1 摘要,進行 BASE64 編碼后寫入 簽名文件,即.SF 文件。具體.SF 文件示例內容下圖所示:

第三步,計算整個.SF 文件的數字簽名,將數字簽名和 開發者X.509 數字證書寫入.RSA 文件。具體.RSA文件示例內容下圖所示:

讀到這里應該已經對Android應用簽名有了比較清晰的了解,最后在介紹一下Android應用簽名都有哪些用處,具體如下圖所示:

1.1.2 iOS 簽名機制和原理

蘋果在iOS2.0版本中引入了強制代碼簽名(Mandatory Code Signing)技術。簽名是iOS設備的安全和蘋果的AppStore生態安全的基礎,通過代碼簽名技術使蘋果公司能夠嚴格控制蘋果設備設備上運行的代碼,可以有效地防止來自外部的攻擊。

蘋果的簽名證書按著使用用途可以分為三類:開發證書、企業證書和發布證書。開發證書是為方便開發人員在應用開發期間頻繁地修改代碼安裝到設備上測試的簽名解決方案。實現原理是分發給開發者一套密鑰和證書,通過這套密鑰和證書對App進行簽名,蘋果對開發者的身份進行“背書”,讓設備信任開發者簽名的應用。

開發者證書需要開發者手動生成,生成開發者證書主要有兩個步驟:第一步,通過密鑰串中的證書助理生成CSR文件(Certificate Signing Request),具體如下圖所示:

完成操作之后會生成一個名為CertificateSigningRequest.certSigningRequest的文件,在生成該文件的同時密鑰串中會自動生成了一對公、私鑰。如下圖所屬:

第二步,在蘋果開發者中心中的Certificates選項中選擇創建一個證書,按要求將第一步中生成的CertificateSigningRequest.certSigningRequest文件上傳便可生成開發者證書。如下圖所示:

企業證書是本質就是蘋果為企業級開發人員提供的簽名證書。使用企業證書簽名的應用可以直接安裝到iOS設備不用提交蘋果審核,只需在應用第一次啟動時信任該證書即可正常使用。企業包常用于內部測試或提供給一些測試用戶做為正式上線前的灰度測試,企業證書簽名的應用無法上架AppStore。

發布證書就是蘋果規定開發者將應用提交AppStore審核前,對應用進行簽名的證書。證書通常命名為iPhone Distribution: xxxxxxxxx,用于AppStore校驗提交上來的App的完整性,只有管理員以上身份的開發者賬號才可以申請,可以控制提交權限的范圍。Distribution證書只能用于正式應用的上架發布,不能用于應用的開發調試。

以開發者證書為例,介紹使用Xcode進行簽名的流程。使用蘋果的私鑰對開發者的公鑰進行簽名并結合開發者的公私生成證書,將證書整合進Provisioning Profiles文件后同樣使用蘋果的私鑰進行簽名。應用開發完成以后使用開發者的私鑰進行簽名,將Provisioning Profiles文件導入應用中打包完成整個簽名打包流程。具體簽名流程如下圖所示:

生成的應用簽名文件CodeResources存放在IPA安裝包的_CodeSignature目錄中。簽名文件中存儲安裝包中所有文件起的簽名信息,具體內容如下圖所示:

iOS系統會在應用安裝時進行簽名校驗,通過校驗后才能正常安裝到設備。簽名校驗流程如下圖所示:

蘋果不僅可以通過簽名保證iOS應用的完整性防止被篡改,還可以根據開發者公鑰生成證書驗證是否為合法的開發者。應用程序只有簽名后才能夠正常使用蘋果的服務,蘋果就是通過這些手段實現其對整個生態的控制。