當前位置:係統粉 >   IT資訊 >   蘋果資訊 >  為什麼有些APP沒有上架AppStore?iOS打包簽名內幕

為什麼有些APP沒有上架AppStore?iOS打包簽名內幕

時間:2020-03-03 來源:互聯網 瀏覽量:

文章轉自:開源中國


iOS簽名類型有Development、AD-Hoc、In-House與App Store,而打包過程中又涉及到各種證書、Provision Profile、entitlements、CertificateSigningRequest、p12、AppID......各種概念一大堆,本文將從打包簽名的原理說起,並梳理完全簽名的整體流程,最後講解重簽名的實現以及簽名機製中有哪些需要注意防護的要點。

為了保證App的分發平台是可控的,以及保證所有安裝到iOS設備上的App都是經過蘋果官方允許的,蘋果建立了iOS簽名打包機製。要了解iOS簽名機製的實現,我們首先從簽名機製的原理說起。

1. 簽名原理1.1 不對稱加密

網絡數據的傳輸可以使用對稱加密以及不對稱加密的方式進行安全防護,對稱加密是指數據發送者(A)和接收者(B)雙方進行加解密的密鑰是一致的,但這樣會增加密鑰自身分發的不安全性:比如要如何保證密鑰在傳遞過程中不被泄露。

而不對稱加密則由A、B持有一對公私鑰進行加解密,公私鑰鑰匙是成對出現的。對於一個私鑰,有且隻有一個與其對應的公鑰,私鑰保密、公鑰公開,但是不能通過公鑰推導出私鑰,使用私鑰加密的文件可用公鑰解密,反過來公鑰加密的文件也隻能用私鑰進行解密。加密過程如下:

發送方(A)首先生成一對公私鑰鑰匙對,私鑰自己保管,公鑰則任意分發出去(每台iOS設備終端其實已經包含Apple的公鑰)。發送數據時,發送方使用私鑰對原數據加密成密文傳輸(加密打包ipa);接收方(B)收到密文後,使用之前已經獲取到的公鑰進行解密得到數據內容(iOS設備驗證安裝ipa)。為什麼有些APP沒有上架AppStore?iOS打包簽名內幕(1)

1.2 數據簽名

這裏主要解決了兩個問題,一個是加密數據大小的問題,另一個是如何驗證公鑰的有效性。

1.2.1 信息摘要

前麵已經講到,iOS打包安裝的過程中會對ipa包進行加解密驗證。然而ipa安裝包大小動輒就有十幾M,大的有好幾G,那如果對這麼大的數據量進行加解密,肯定效率是非常低的。而信息摘要則是解決了加密數據過大的問題,其原理是對信息內容通過一個很難被逆向推導的公式計算得到一段哈希數值,它具有以下特點:

計算得到的哈希值大小固定,不受原本信息內容大小的影響;不可逆,根據哈希值無法推斷得到原本信息(實際上MD5以及SHA-1算法已經被證明可以被破解);唯一性,原本信息內容一致,那麼哈希值也一致;原數據不同,也不會存在重複的哈希結果。

使用信息摘要技術在數據加密傳輸時,發送方先對文件內容使用哈希算法進行信息摘要計算,再對摘要內容進行加密,之後將文件內容以及摘要內容(已加密)發送出去。

接收方收到數據後,先解密得到摘要內容,再依據相同的哈希算法對文件內容進行信息摘要計算,最後匹配接收到的哈希值與計算得到的哈希值是否一致,如果一致那就說明傳輸過程是安全的。

這樣也就避免了對整體原數據加解密的計算過程,從而提高了驗證效率。

1.2.2 簽名證書

不對稱加密中的公鑰是公開的,誰都可以得到,這樣也就存在了不安全性。比如主動攻擊者C冒充數據發送者A,將自己偽裝後的公鑰分發給數據接收者B,從而達到監聽A、B之間通信的目的,又或者是對A、B之間的通信數據進行注入攻擊。

為什麼有些APP沒有上架AppStore?iOS打包簽名內幕(2)

那為了保證獲取公鑰的安全性,這裏引入CA認證(Certificate Authority)。CA是證明公鑰合法性的權威機構(Apple就屬於CA認證機構),它為每個使用公開密鑰的用戶發放一個數字證書,數字證書的作用是證明證書中列出的用戶合法擁有證書中列出的公開密鑰。用戶使用CA的公鑰對數字證書上的簽名進行驗證,如果驗證通過,也就認為證書內包含的公鑰是有效的。

為什麼有些APP沒有上架AppStore?iOS打包簽名內幕(3)

CA認證確保了用戶公鑰使用過程中的安全性,iOS打包需要向蘋果開發者中心上傳.certSigningRequest文件,然後配置得到各種.cer證書,這些流程中便包括了開發者向Apple CA認證中心注冊公鑰的過程。

2. iOS簽名2.1 概念要點.certSigningRequest 文件。從Mac的鑰匙串訪問中生成.certSigningRequest文件,這個過程會從Mac終端生成一對鑰匙對,私鑰存儲在Mac中,公鑰則包含在.certSigningRequest中。再將.certSigningRequest文件上傳到Apple後台即蘋果開發者中心,則可以對應生成開發證書或者發布證書(.cer文件)。.cer 文件:Apple後台使用Apple私鑰對Mac公鑰進行簽名後生成的證書。.p12 文件:Mac本地生成的鑰匙對私鑰。由於私鑰是本地私有的,但你可以使用.p12將私鑰導出給其他團隊成員使用。Identifiers。Identifiers是iOS設備安裝應用時用來識別不同App的唯一標識,點擊創建App IDs,同時勾選app所包含的權限:APNs、HealthKit、iCloud等。entitlements。App使用到的各種權限(APNs、HealthKit、iCloud等),也是需要Apple驗證通過後才能生效的,Apple將這些權限開關統一稱為Entitlements。當第一次在Xcode中勾選權限時,項目中會自動生成一個.entitlements後綴的文件,裏麵記錄了App所擁有的權限。Profiles。.cer文件隻是聲明了證書的類型,比如Apple Development、Apple Distribution、APNs推送等等,而至於使用什麼證書打包、AppID是什麼、打包的App包含了哪些功能、可以在哪些設備上安裝,則是通過Provisioning Profile 描述文件(.mobileprovision後綴)來說明的,蘋果後台將所有這些信息組合後再使用Apple私鑰進行簽名,最後生成Provisioning Profile描述文件:2.2 AppStore簽名

發布App至AppStore之前需要經過蘋果後台審核,審核通過蘋果後台會用Apple私鑰對App數據進行加密簽名生成ipa包;用戶從AppStore下載App後,使用設備內置的Apple公鑰解密驗證,驗證通過安裝成功。由於AppStore分發的過程中上傳審核、下載安裝的整個過程都處在蘋果的生態鏈內,所以隻需要一次驗證就能保證安全性。

為什麼有些APP沒有上架AppStore?iOS打包簽名內幕(4)

2.3 其他簽名

從AppStore下載安裝App隻需要一次數字簽名就足以保證安全性,但除了這種途徑蘋果還有其他的安裝方式:

開發中連接設備到Xcode進行調試安裝AD-Hoc內部測試安裝,需要先獲取設備UDID並注冊,並且有最多100台設備的限製In-House企業內部分發,安裝設備數量無限製,但安裝後需主動在設置中選擇信任證書

那這些安裝App的過程中蘋果又是怎樣保證流程安全性的呢?答案就是雙重簽名機製,蘋果使用前麵講到的Mac本地鑰匙對以及Apple後台鑰匙對進行多次數字簽名,從而保證整體流程的可控。

Mac 鑰匙串訪問 在本地生成一對公私鑰鑰匙對,下麵默認為公鑰L、私鑰L(L:Local)。Apple已有一對公私鑰鑰匙對,私鑰A在Apple後台,公鑰A內置到每一台iOS設備終端(A:Apple)。上傳公鑰L至Apple後台,使用私鑰L對公鑰L進行數字簽名生成簽名證書.cer,同時使用私鑰L對額外信息(使用什麼證書打包、AppID、打包的App包含了哪些功能、可以在哪些設備上安裝)進行簽名生成描述文件Provisioning Profile,之後將.cer和Provisioning Profile下載安裝到Mac機器上。編譯打包app,選擇簽名證書.cer,打包指令會自動找到該證書對應的私鑰L(能匹配是因為鑰匙對是成對出現的,前提是本地必須已經存在L私鑰,也就是p12的安裝),然後使用私鑰L對app進行簽名。這些簽名數據包含兩部分:Mach-O可執行文件會把簽名直接寫入這個文件中,其他資源文件則會保存在_CodeSignature目錄下。你可以將打包生成的.ipa文件另存為.zip,解壓後對Payload文件夾中的.app文件右鍵、顯示包內容,就可以看到簽名數據。另外簽名過程中對於App內包含的動態庫以及插件(Plugins、Watch、Frameworks文件夾),每一個都會單獨進行一次簽名,並生成各自的Mach-O可執行文件和_CodeSignature。簽名數據指代碼內容、App包含的所有資源文件,隻要其中有任何改動,都必須重新簽名才有效。打包的過程中會將描述文件Provisioning Profile命名為embedded.mobileprovision放入到打包app中。安裝/啟動,iOS設備使用內置的公鑰A驗證embedded.mobileprovision是否有效(設備是否在允許安裝列表內),同時再次驗證裏麵包含的.cer證書簽名是否有效(證書過期與否)並取出公鑰L。embedded.mobileprovision驗證通過,就使用公鑰L解密驗證app簽名信息:AppID是否對應、權限開關是否跟app裏的entitlements一致等等。所有驗證通過,安裝/啟動完成。為什麼有些APP沒有上架AppStore?iOS打包簽名內幕(5)

以上流程便是開發調試、AD-Hoc、In-House等方式打包安裝App的過程,區別隻在於第⑤步中設備IDs的匹配規則不一致。開發調試隻安裝當前聯調的設備;AD-Hoc允許安裝到已在開發者賬號下注冊過的設備,且每年最多允許100台;In-House無設備數量限製,常用於企業內部App的分發。

3. ipa包重簽名

ipa包重簽名主要針對的是非App Store的安裝包,App Store分發最終是上傳ipa文件到蘋果後台審核,通過後使用Apple私鑰加密,然後才能發布安裝,不存在重簽入侵的可能。而開發調試、AD-Hoc、In-House等分發途徑生成的ipa包不存在蘋果後台驗證的步驟,這也就意味著你可以對任意的.app、 .ipa文件進行重簽名。

回顧前麵講到的簽名流程,真正對ipa包進行簽名的關鍵步驟(④⑤)是在Mac本地進行的,簽名過程中需要滿足三個條件:App即軟件代碼編譯生成的產物、p12證書以及Provisioning Profile配置文件。其中App的內容是動態變動的,Apple不會去驗證它,實際上也無需驗證,因為在開發調試過程中,所開發的App肯定是不停的迭代變化的,如果需要上線App Store那Apple隻需在審核階段對App內容進行把關驗證即可,而其他分發渠道它則管不了。p12以及Provisioning Profile則是下載後主動安裝的,大部分情況下都是由管理員創建下載好之後,導出分發給團隊成員。

3.1 簽名指令

iOS簽名調用的是codesign指令,你也可以直接使用相關指令進行簽名,下麵是codesign的常用指令:

3.2 重簽名首先獲取需要重簽名的ipa包,注意該ipa包必須是未加密的。如果是從App Store下載的ipa,需要砸殼解密後才能進行重簽名,你也可以從越獄平台下載。將獲取的.ipa重命名為.zip,然後右鍵解壓,將會生成一個 Payload 文件夾,裏麵包含.app文件。將簽名證書對應的Provisioning Profile文件重命名為 embedded.mobileprovision,並拷貝放到Payload文件夾中。同時右鍵.app文件,顯示包內容,將前麵的embedded.mobileprovision文件再拷貝一份放到.app文件夾中,替換掉原有的embedded.mobileprovision。entitlements.plist是由簽名證書對應的Profile配置導出的簽名文件,它與前麵截圖Xcode簽名日誌中的XXX.xcent文件的作用相同。終端cd到Payload文件夾路徑,執行指令# cd xxx/Payload,然後執行下麵指令 security cms -D -i embedded.mobileprovision將會打印出Profile配置的內容,找到Entitlements,然後把Entitlements下麵...的內容拷貝到新建的entitlements.plist文件中(可以通過Xcode生成plist文件,選Property List類型),最後將entitlements.plist文件放到Payload文件夾中。# 拷貝內容為: ... Entitlements application-identifier xxx keychain-access-groups xxx get-task-allow com.apple.developer.team-identifier xxx 簽名證書名稱可以在安裝證書後從鑰匙串中心查看或者在終端使用以下指令查看:security find-identity -v -p codesigning準備工作完成,開始重簽名。先右鍵.app顯示包內容,查看動態庫和插件(Plugins、Watch、Frameworks文件夾),如果是個人證書需要移除Plugins、Watch文件夾,因為個人證書沒法簽名Extention。如果存在Frameworks,則執行簽名指令,有多個的話則每一個Frameworks都要重簽一次。codesign -fs "簽名證書名稱" "Frameworks/xxx.framework(動態庫路徑)"最後對app進行重簽名codesign -f -s "iPhone Distribution: XXX(證書名稱)" --entitlements entitlements.plist(Profile配置文件) XXX.app(簽名app)最後將Payload文件夾下的資源移除,隻保留.app文件,右鍵壓縮,然後更改後綴為.ipa,這樣重簽後的ipa便已生成了,你可以通過iTunes、iTools或其他途徑安裝到iOS設備上。3.3 注入代碼重簽ipa代碼注入一般通過動態庫來實現。新建動態庫在Xcode中選擇新建 TARTETS — Framework & Library — Framework,然後在framework中添加自定義代碼,一般都是使用Runtime來注入附加功能。最後選擇framework要支持的架構,編譯後便得到了最終動態庫。對需要重簽名的.app右鍵顯示包內容,然後將動態庫拷貝到Framework文件夾(沒有則新建)中。然而此時動態庫與app還沒建立關聯關係,動態庫需要注入MachO中才能生效。注入使用yololib工具,下載yololib並編譯,將生產的命令複製到/usr/local/bin或$PATH中的其他路徑,便可以在終端使用yololib指令## 通過yololib工具實現注入動態庫 yololib "MachO文件路徑" "需要注入的動態庫路徑"注入成功後再對所有Framework簽名,最後對app重簽名,然後生成ipa文件。這裏整理了一份用於重簽名的腳本 CJCodeSign,想了解更多關於簽名指令的內容可點擊查看詳情。3.4 關於重簽名的思考

iOS重簽名實現,可以發現用於簽名的私鑰資源(包括.cer證書和Provisioning Profile配置)和實際簽名的app包是沒有強關聯關係的,這也就帶來了兩方麵的問題。

.cer證書和Provisioning Profile配置被用於其他App的分發簽名,特別如果是In-House企業類型的證書,那是可以進行無限製分發的,而一旦蘋果檢測到這種違規簽名的行為,輕則撤銷證書,重則注銷企業開發者賬號!這也就是為什麼一定要嚴格把控 p12、Provisioning Profile 文件外發的原因。自有App被注入代碼後重簽名,比如應用多開、添加插件、惡意抓包等等,對於這一類的防護除了對Bundle ID進行檢查,以及對App動態庫增加白名單檢索外好像也沒有更好的辦法。當然這已經涉及到逆向防護的方向了,本人對此還未深入了解,有興趣的同學可以一起參與探討。

全文完!

最後再附上重簽名腳本地址: CJCodeSign

作者簡介:

lele8446,iOS開發深耕者,愛好分享、深⼊探討有溫度的內容,GitHub地址。

我要分享:

最新熱門遊戲

版權信息

Copyright @ 2011 係統粉 版權聲明 最新發布內容 網站導航