iOS 應用簽名原理&重簽名
在蘋果的日常開發中,真機測試與打包等很多流程都會牽扯到各種證書,CertificateSigningRequest,p12等。但是很多相應的開發者並不理解iOS App應用簽名的原理和流程。今天著重講解一下此內容。
思考
在蘋果的iOS系統出來之前,以前的主流程Mac OS/Window軟體存在著安全隱患,盜版軟體,病毒入侵等,蘋果希望能解決類似的問題,保證每一個安裝在蘋果手機上的app都是經過蘋果官方允許的,怎麼保證呢?
一、iOS 應用簽名原理
1 程式碼簽名
要想回答上面“思考”的答案,首先我們講解一個概念。程式碼簽名:是對可執行指令碼或者檔案進行數字簽名,用來保證軟體在簽名後未被損害或者修改的措施。
2 簡單的程式碼簽名
最簡單的驗證方式是通過蘋果官方生成非對稱加密的一對公私鑰。私鑰儲存在Appstore的伺服器,而公鑰儲存在iOS系統中,蘋果後臺用私鑰來對App資料進行簽名,iOS系統下載此APP後,用公鑰來驗證簽名。若驗證成功,說明該App未被更改,可以安裝到手機中,反之,則不行。
上面的驗證可以解決大部分App入駐手機中的場景,但是對於我們開發蘋果應用的開發者而言,我們也可以直接通過真機測試進入到使用者的手機,而且蘋果也有企業使用者渠道,所以如果想要全方面的安全的安裝蘋果App,就無法通過簡單的程式碼簽名做到,那麼蘋果又是通過怎樣的方案呢?
3 雙層簽名
下面流程圖
解釋如下:
- 首先Mac電腦通過CSR檔案申請證書(通過公鑰M)
- 蘋果伺服器返回公鑰M以及公鑰M算出的雜湊值(也就是簽名)
- App包裡包括可執行檔案MachO,然後對MachO通過私鑰M簽名(App簽名)並將證書放到App中
- 然後將App放入到iphone中。首先將App中的證書拿出來解析,誰能解析App的證書,因為App的證書是由蘋果伺服器拿著私鑰A中進行加密的,也只有公鑰A能解密出來,也就是iphone中儲存的公鑰A,通過驗證檢視App是否被修改;然後再去驗證App的簽名,怎麼驗證App的簽名呢,(App簽名是通過Mac 電腦的私鑰M進行加密的,也只有證書中的公鑰M進行解密)就這樣經過了兩層驗證!
通過上面的講解,是不是發現特別的安全了?其實不然,因為大部分的應用都是通過AppStore進行安裝,如果通過上面的過程可以安裝所有的蘋果裝置,那麼還需要要Appstore幹嘛,這時候蘋果防止濫用App,就做了兩條限制:
- 經過蘋果伺服器中註冊過的裝置
- 簽名只能具體到某一個App進行簽名(推送,授權等)
經過上面的講解,也引出了另一個概念-描述檔案。
4 描述檔案
描述檔案又稱為Provisioning profile,一般包括了三樣東西:
- 證書
- AppId
- 裝置
當我們打包或者是真機執行的時候,通過證書來驗證程式的安全性和合法性。
並且在App的使用中,蘋果還想控制App裡面的推送/iCloud及後臺執行等這些的許可權,蘋果將這些許可權開關統稱為授權檔案-Entitlements,並將檔案放在了描述檔案中。
在開發中,編譯一個App後,會用本地的私鑰M對App進行簽名,同時從蘋果伺服器得到的描述檔案打包進App裡為embeded.mobileprovision,把App安裝在手機中,最後系統進行來驗證。
上面的圖也會變為如下:流程就是將描述檔案加入,解決上面的問題?
5 拓展
首先我們做一個demo講解App包內容。
- 首先看工程檔案1-products檔案,點選開啟Demo.app,顯示包內容,緊接著出現2-內容
- 檢視有_Codesignature,是資原始檔簽名;embedded.mobileprovision是上面說的描述檔案;另外我們看下可執行程式碼,也就是MachO檔案,放在了001--Demo中,也就是黑色的一個,通過MachOView中可以檢視MachO檔案。開啟之後,程式碼簽名放在MachO中如下:
也就是Code Signature--程式碼簽名。
但是我們是做逆向開發,所以我們要學會應用重新命名!!!
二、iOS 應用重簽名
在講解重簽名中,首先學下終端命令:
當我們從AppStore上下載App後,如果做了相應的更改,又怎麼會在手機上執行起來呢?這就需要應用重簽名,並且Xcode給我們提供了重簽名技術-codesign技術。
拓展:我們首先來講解一下怎麼獲取應用的ipa包?
- 助手裡面下載
- 越獄手機裡面進行拷貝
- iTunes下載(12.6.3)
1 下面我們將以在iTunes 12.6.3 下載了兩個版本的微信,一個為正版,一個為盜版的分別進行簽名!
通過微信-6.7.3(越獄應用)顯示包內容,看出對應的子目錄,檢視playload資料夾,發現WeChat.app
2然後通過終端命令,otool -l WeChat | grep crypt 檢視篩選後的cryp,得到如下:
通過上面的發現cryptid = 0 代表是該App不是加密的,非0時代表是加密的。假如cryptid=1 代表是用1這種方式加密,不代表用1加密。
上面顯示為什麼有兩個cryptid = 0 ,下面的輸入命令解釋了為何有兩個:通過命令file WeChat
檢視有Mach-O中有兩種架構,Mach-O executable arm_v7和Mach-O 64bit executable arm64兩個,arm_v7代表5s之前的手機,arm64代表的是5s手機之後
3 對越獄微信開始重簽名,因為cryptid = 0
3.1 刪除多餘的越獄微信包內容
3.2 對Framework進行重簽名:codesign -fs “自己的開發證書” framework
下面是通過終端命令的截圖,完成對截圖內的Framework進行重簽名。
3.3 下面要對App包整個重籤,也就需要對描述檔案進行重籤。首先將描述性檔案放入到越獄微信包下(描述性檔案必須要與boundId一致,infoPlist檔案檢視)
開始要許可權plist檔案,將entitlements.plist放到了weChat.app同等級目錄中
我們看WeChat.app中,該刪的已經刪掉,framework重籤,以及描述性檔案加進去,下面用entitlements.plist對整個App包簽名。
通過命令codesign -fs “自己證書” --no-strict --entitlements=entitlements.plist WeChat.app,對包簽名
緊接著通過檢視codesign -d -vv WeChat.app命令檢視重簽名成功沒,上面的截圖中,發現證書已經變為了自己的,說明重簽名成功。
結合著xcode與描述性檔案,就可以在手機上執行。
上面重簽名的步驟,可能並不是很清晰,又準備了一個總結如下:
三、拓展
3.1 Shell指令碼
Shell指令碼為使用者提供了啟動程式,管理系統的檔案以及執行在系統上程序的途徑。Shell在開發中一般指命令列工具,它允許輸入文字的命令,然後解釋命令,最後在核心中執行。Shell指令碼,也是用各類命令預先放入到檔案中,方便一次性執行的指令碼檔案。
下面我們用demo方式講解shell命令:
首先通過命令建立資料夾,並在資料夾下建立“國孩”文字
檢視桌面內容如下:
如果想這些命令一次性的執行,可以嘗試寫一個指令碼檔案
然後進入到編輯頁面,將內容輸入進去
最後生成檔案如下,也能完成目的
看到上面之後,使用到了bash,除了bash,還有zsh,Source等命令效果都是一樣的,怎麼檢視mac支援哪些呢?
通過cd /private/etc,以及cat shells,
通過上面的都可以滿足建立123.txt。
但是上面的各個指令也有一定的區別,如下:
3.2 使用者、組、許可權
也是以Demo的形式進入,在桌面上新建一個Demo資料夾。通過命令ls -l命令檢視demo的檔案許可權
前面有一排-rw-r--r--等,大家可能不知道什麼意思,下面我們來講解:通過一幅圖
上面就是檔案型別與許可權。
上面的許可權可不可以更改呢,對於逆向開發的人員,不是沒有東西是不可以更改的,下面我們來講述下更改檔案型別和許可權。
通過一幅圖來講解檔案更改的基本內容和指令:
再以Demo的方式進行講解:
更改guohai.sh檔案許可權,取消所有許可權(非讀非寫非執行)
再將user,group以及其他設定為可讀,執行如下:
還有其他很多命令,大家可以根據上圖自己嘗試。
四、指令碼重簽名
學了上面的指令碼,就是為了下面所講的內容-指令碼重簽名服務的,利用指令碼進行重簽名。
首先開啟專案工程-->build phases -->選擇如下:建立一個script指令碼
建立之後
然後我們按照如下步驟進行指令碼簽名
# ${SRCROOT} 它是工程檔案所在的目錄 TEMP_PATH="${SRCROOT}/Temp" ASSETS_PATH="${SRCROOT}/APP" TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa" #清空Temp資料夾 rm -rf "$TEMP_PATH" mkdir "$TEMP_PATH" #1.1將IPA解壓到Temp下 unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH" #1.2拿到解壓臨時的APP路徑 TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1") echo "TEMP: