在iOS系統出來以前,主流的操做系統(Mac或者Windows)軟件隨便從哪裏下載都能安裝,運行,系統安全存在隱患,盜版軟件,病毒入侵,靜默安裝等等問題,蘋果但願iOS的系統上不會出現這樣的問題,就要保證每個安裝到iOS系統上的APP都是通過蘋果官方容許的,那麼蘋果是如何作到的呢?ios
蘋果服務器生成一對RSA的公鑰A和私鑰A,私鑰A服務器保存,公鑰A分給每一臺iOS設備,服務器對每一個APP使用私鑰A簽名,iOS設備在安裝APP的時候,使用內置的公鑰A對APP進行驗證,只有經過驗證了的APP才容許安裝,這樣就能夠保證安裝的APP都是通過蘋果容許的了;git
或許蘋果在沒有開放App Store給廣大開發者的時候,這樣簡單的代碼簽名就夠了;可是後來隨着蘋果對App Store的開放,我的開發者,公司開發者隨時都須要鏈接真機調試開發APP;還有企業開發者須要在企業內部分發APP,而不須要上傳App Store,須要作到開放這些方式安裝APP,同時還要保證這些安裝行爲是可控的,那麼上面所講簡單的代碼簽名就沒法實現了github
咱們分析一下蘋果對於APP安裝的需求:shell
爲了實現這些需求,iOS代碼簽名的複雜度也就增長了,蘋果實現的方案是雙重簽名緩存
除了上傳到App Store的APP能夠下載安裝以外,開發人員也能夠直接使用Mac系統將開發中的APP安裝到iPhone手機上,可是這個安裝行爲也是須要蘋果容許的;安全
作過iOS開發的同窗應該知道,當須要將Xcode開發的APP安裝到真機上的時候,Xcode會在Signing & Capabilities下給出紅色的錯誤,提示開發者Signing for "xxx" requires a development team.
意思簽名你開發的APP須要一個開發團隊,這個開發團隊就是由證書(Signing Certificate)和描述配置文件(Provisioning Profile)組成的;關於描述配置文件,咱們放在後面再說;那這個證書(Signing Certificate)是怎麼來的呢?服務器
當咱們使用Mac上的Xcode安裝APP的時候,Xcode會在咱們的Mac電腦上生成一對RSA的公鑰M和私鑰M(M=Mac);而後將公鑰M經過CSR(Certificate Signing Request)文件向蘋果服務器請求籤名;微信
以前說了蘋果服務器和iOS系統之間是有一對公鑰A和私鑰A的(A=Apple)markdown
蘋果服務器收到CSR文件以後,會使用本身的私鑰A對公鑰M的hash進行簽名,這樣公鑰M和通過蘋果服務器私鑰A簽名過的hash組成一份文件返回給Mac系統了,這份文件就叫作證書;咱們打開Mac系統上的鑰匙串訪問就能看到許多的證書,點擊簽名的箭頭還能看到對應的私鑰M;app
在開發過程當中,編譯完一個APP後,用本地的私鑰M(或者別人給你的p12)對這個APP進行簽名,同時把上一步獲得的證書一塊兒打包進APP裏,安裝到手機上
在安裝APP時,iOS系統獲取APP包裏的證書,經過iOS系統內置的公鑰A,去驗證這個證書籤名是否正確
驗證經過以後,就說明證書裏的公鑰M是沒有通過篡改的,再使用這個公鑰M去驗證APP的簽名,若是經過了驗證就說明APP也是沒有被篡改過,能夠安裝的
有了上面的過程,已經能夠保證開發者的認證,和程序的安全性了。可是,要知道iOS的程序,主要渠道是要經過APP Store才能分發到用戶設備的,若是隻有上述的過程,那豈不是隻要申請了一個證書,就能夠安裝到全部iOS設備了?描述文件的做用就來了
描述文件(Provisioning profile)通常包括三樣東西:證書、App ID、設備。當咱們在真機運行或者打包一個項目的時候,證書用來證實咱們程序的安全性和合法性。
蘋果爲了解決應用濫用的問題,因此蘋果又加了兩個限制:
而且蘋果還想控制App裏面的iCloud/PUSH/後臺運行/調試器附加這些權限,因此蘋果把這些權限開關統一稱爲Entitlements(受權文件).並將這個文件放在了一個叫作Provisioning Profile(描述文件)文件中.
描述文件的存放路徑:~/Library/MobileDevice/Provisioning Profiles
描述文件是在AppleDeveloper網站建立的(在Xcode中填上AppleID它會代辦建立),Xcode運行時會打包進入APP內.因此咱們使用CSR申請證書時,咱們還要申請一個東西!! 就是描述文件!
在開發時,編譯完一個 APP 後,用本地的私鑰M對這個APP進行簽名,同時把從蘋果服務器獲得的 Provisioning Profile文件打包進APP裏,文件名統一改成embedded.mobileprovision,把 APP 安裝到手機上.最後iOS系統進行驗證。
終端查看描述文件內容:security cms -Di embedded.mobileprovision
能夠看到就是一個plist文件,裏面有不少鍵值對,其中key爲entitlements,這個鍵值對在後面使用codesign重籤應用的時候會用到
最終的流程以下圖所示: 能夠看到iPhone手機在安裝APP的時候,先使用iOS系統內置的公鑰A去驗證APP內部的公鑰M(公鑰M被蘋果服務器的私鑰A簽名了),驗證經過以後的公鑰M再去驗證當前的APP(當前APP被私鑰M簽名了),驗證經過以後才能夠進行安裝行爲;
瞭解了iOS應用的簽名原理以後,咱們是否是能夠作一個大膽猜測,對於任何不是咱們開發的APP,咱們能不能使用咱們的描述文件和證書來從新簽名,別人的APP通過咱們重籤後就會被Xcode認爲是咱們當前正在開發的APP,從而能夠附加調試了;實際上,咱們確實能夠對任何來源的APP進行重籤和附加調試,可是前提是這個APP必須是砸殼過的APP,pp助手iOS版下架後,如今網上砸殼過的APP很差找了,就只有本身動手砸殼了,這個咱們之後會講,若是有須要的能夠私我
codesign 是Xcode自帶的簽名工具,咱們能夠先使用它來幫我完成重簽名,後面也能夠直接使用Xcode進行重籤;
下面先介紹一下相關一些命令:
codesign -vv -d xxx.app
查看xxx.app的一些簽名信息
security find-identity -v -p codesigning
查看當前電腦上的證書
otool -l xxx | grep cryptid
查看MachO文件xxx並篩選結果包含cryptid的信息,能夠根據cryptid的值肯定當前APP是否加密,1表明加密,0表明未加密
otool -l xxx > ~/Desktop/123.txt
查看MachO文件xxx,並將結果以123.txt保存在桌面
咱們以微信爲例子來進行重簽名,在拿到已經砸殼過的微信ipa包以後,用歸檔實用工具解壓 咱們只須要Payload裏面的.app包
右鍵.app包顯示包內容後,開始下面的步驟
沒有權限的二進制文件是白色的 提高權限以後變成黑色的
再將新建Demo的描述文件,複製到WeChat.app內
把WeChat.app裏面的info.plist的BundleID改成新建的Demo的BundleID
受權文件在描述文件裏面,輸入security cms -Di embedded.mobileprovision
能夠查看描述文件具體信息 找到裏面key爲Entilements的這一部分,把紅圈起來的部分複製並新建一個新的plist文件保存下來
再把這個plist文件,放到和WeChat.app同目錄下,準備重籤
打開終端,輸入如下命令進行重籤:codesign -fs "你的證書" --no-strict --entitlements=ent.plist WeChat.app
可使用
codesign -vv -d WeChat.app
命令查看咱們是否成功重簽了,變成你的證書和BundleID就表明成功了 到此,這個WeChat就被咱們重籤成功了!!!此時,咱們可使用Xcode將這個WeChat安裝到咱們的手機上
若是你的手機上原本有一個官方正版微信,你如今會發現手機上出現了兩個微信;接下來你能夠打開剛剛新建的WeChatDemo項目,選擇Debug->Attach to Process->WeChat,若是有兩個WeChat能夠把正版的WeChat從後臺劃掉,或者選擇後面數字較大的那個WeChat,你會發現微信就這樣被咱們的WeChatDemo項目鏈接起來了...能夠對微信像調試咱們本身APP同樣viewDebug了
經過使用codesign手動重簽過程後,發現其實上述過程並不難,只是過程特別的複雜和繁瑣,Xcode能夠幫咱們簡化一些複雜繁瑣的過程,那麼如今咱們直接使用Xcode來重籤;
這裏須要注意一下,由於老版本微信(這裏使用的WeChat版本是7.0.7)是沒有SceneDelegate的,因此新工程也要把SceneDelegate幹掉,跟沒有這個東西以前同樣;(刪掉SceneDelegate的.h和.m文件;AppDelegate添加window屬性並初始化,刪除UISceneSession lifecycle相關代碼;info.plist文件中刪掉Application Scene Manifest字段)
把新建工程的APP包替換成剛剛重簽過的APP包
最後在新工程的下command + R或者點擊運行按鈕,就會發現別人的項目被咱們的Xcode跑起來了
對比下來發現使用Xcode來重籤並附加調試別人的APP仍是要簡單方便一點
通過上述兩種手動重籤的以後,咱們知道了重籤的原理了,那麼咱們能夠將上面的手動簽名的步驟寫成腳本,讓Xcode來執行咱們的腳本進行自動重籤,腳本我已經準備好了,下面是使用腳本重籤的步驟:
這一步仍是跟以前同樣,爲了把描述文件安裝到真機上,可是使用腳原本重籤的話就不須要新建一個跟待重籤APP同名的工程了
由於腳本須要知道重籤的ipa在哪,就規定了一個路徑,就是工程根目錄下新建一個APP目錄,並把ipa包放在裏面
腳本放到工程根目錄下後,咱們能夠按下圖所示的配置好腳本,其中${SRCROOT}是Xcode環境變量,表明了項目的根目錄,而appSign.sh就是咱們的腳本文件
接下來command + R運行就能夠運行並調試他人APP了,有可能報一些權限問題安裝不了啥的,那就Command + shift + k清一下緩存再command + R運行,用上腳本以後可真是太舒服了,那爲何還要講之那些手動重籤的步驟呢...固然是學習腳本背後的原理啊
github地址:github.com/DanTheMan82… 這是一個Mac上的APP,能夠用來給企業開發者帳號重籤別人開發的APP來分發的,不過底層的原理也是相似的,只是用途不同