應用簽名原理
程式碼簽名
概念性的東西:程式碼簽名是對可執行檔案或指令碼進行數字簽名.用 來確認軟體在簽名後未被修改或損壞的措施。和 數字簽名原理一樣,只不過簽名的資料是程式碼而已。
在iOS出來之前,以前的主流作業系統(Mac/Windows)軟體隨便從哪裡下載都能執行,系統安全存在隱患,盜版軟體,病 毒入侵,靜默安裝等等.那麼蘋果希望解決這樣的問題,要保證每一個安裝到 iOS 上的 APP 都是經過蘋果官方允許的,怎樣 保證呢?就是通過程式碼簽名。
如果要實現驗證.其實最簡單的方式就是通過蘋果官方生成非對稱加密的一對公私鑰.在iOS的系統中內建一個公鑰,私鑰 由蘋果後臺儲存,我們傳APP到AppStore時,蘋果後臺用私鑰對APP資料進行簽名,iOS系統下載這個APP後,用公鑰驗證這個簽名, 若簽名正確,這個APP肯定是由蘋果後臺認證的,並且沒有被修改過,也就達到了蘋果的需求:保證安裝的每一個APP都是經過蘋 果官方允許的.
如果我們iOS裝置安裝APP只從App Store這一個入口這件事就簡單解決了,沒有任何複雜的東西,一個數字簽名搞定. 但是實際上iOS安裝APP還有其他渠道.比如對於我們開發者iOSER而言,我們是需要在開發APP時直接真機除錯的.而且蘋
果還開放了企業內部分發的渠道,企業證書籤名的APP也是需要順利安裝的. 蘋果需要開放這些方式安裝APP,這些需求就無法通過簡單的程式碼簽名來辦到了。
蘋果需求
- 安裝包不需要上傳到App Store,可以直接安裝到手機上.
- 蘋果為了保證系統的安全性,又必須對安裝的APP有絕對的控制權
• 經過蘋果允許才可以安裝
• 不能被濫用導致非開發APP也能被安裝
所以為了實現這些需求,iOS簽名的複雜度也就開始增加,蘋果給出的方案,就是雙層簽名。
雙層程式碼簽名
iOS的雙層程式碼簽名流程簡單梳理,這也不是最終的iOS簽名原理.iOS的最終簽名在這個基礎上還要稍微加 點東西.
首先這裡有兩個角色.一個是iOS系統 還有一個就是我們的Mac系統.因為iOS的APP開發環境在Mac系統下.所以這 個依賴關係成為了蘋果雙層簽名的基礎.
1、在Mac系統中生成一對非對稱加密演算法的公鑰和私鑰,這裡簡稱公鑰M和私鑰M。
2、蘋果自己也有一對固定的公鑰A和私鑰A,公鑰A在每個手機iOS系統中,而私鑰A在蘋果後臺。
3、在專案打包過程中,我們第一件事,就是生成CSR檔案,生成檔案的時候,電腦會讓我們填入相關開發者資訊,這些就是所謂的資訊摘要。把CSR檔案(包含公鑰M以及開發者資訊)傳送給蘋果後臺,蘋果後臺用私鑰A去簽名公鑰M,得到了一份資料包含了公鑰M以及其簽名,這份資料稱為證書,以及會給我們一份描述檔案(通過填寫裝置ID、AppID、證書等資訊得到的(Provisioning profile)。
4、在開發時,編譯完一個APP後,用本地的私鑰M(其本質就是P12檔案)對這個APP進行簽名,同時把第三部得到的描述檔案及證書一起打包進APP裡,安裝到手機上。
5、在安裝時,iOS系統取得證書,通過系統內建的公鑰A,去驗證證書的數字簽名是否正確。
6、驗證證書後確保了公鑰M是蘋果認證過的,再用公鑰 M 去驗證 APP 的簽名,這裡就間接驗證了這個 APP 安裝 行為是否經過蘋果官方允許。(這裡只驗證安裝行為,不驗證APP 是否被改動,因為開發階段 APP 內容總是 不斷變化的,蘋果不需要管。)
如果你還是不太明白,就仔細看一下下面的流程圖。
有了上面的過程,已經可以保證開發者的認證,和程式的安全性了。
描述檔案
描述檔案(Provisioning profile)一般包括三樣東
西:證書、App ID、裝置。當我們在真機執行或
者打包一個專案的時候,證書用來證明我們程式
的安全性和合法性。
蘋果為了解決應用濫用的問題,所以蘋果又加了兩個限制. 第一限制在蘋果後臺註冊過的裝置才可以安裝. 第二限制簽名只能針對某一個具體的APP. 並且蘋果還想控制App裡面的iCloud/PUSH/後臺執行/偵錯程式附加這些許可權,所以蘋果把這些許可權開關統一稱為
Entitlements(授權檔案).並將這個檔案放在了一個叫做Provisioning Profile(描述檔案)檔案中. 描述檔案是在AppleDevelop網站建立的(在Xcode中填上AppleID它會代辦建立),Xcode執行時會打包進入APP內. 所以我們使用CSR申請證書時,我們還要申請一個東西!! 就是描述檔案!
在開發時,編譯完一個 APP 後,用本地的私鑰M對這個APP進行簽名,同時把從蘋果伺服器得到的 Provisioning Profile 檔案
打包進APP裡,檔名為embedded.mobileprovision,把 APP 安裝到手機上.最後系統進行驗證。
重簽名原理
codeSign
Xcode提供了簽名工具,codesign,我們通過幾個命令就可以完成重簽名。日常我們開發中,簽名的過程都是Xcode代替我們手工完成。
相關終端命令
$security find-identity -v -p codesigning //列出鑰匙串裡可簽名的證書
複製程式碼
$Codesign –fs “證書串” //檔名 強制替換籤名
複製程式碼
$Chmod +x 可執行檔案 //給檔案新增許可權
複製程式碼
$security cms -D -i ../embedded.mobileprovision //檢視描述檔案
複製程式碼
$codesign -fs “證書串” --no-strict --entitlements=許可權檔案.plist APP包
複製程式碼
$Zip –ry 輸出檔案 輸入檔案 將輸入檔案壓縮為輸出檔案
複製程式碼
重籤步驟
說在前面的一些注意事項,因為剛開始接觸逆向,所以現在pp助手下載越獄的ipa包。越獄的ipa包是非加密包,可以通過幾項操作查詢到該ipa包是否加密
以下我們用微信舉例:
1、下載越獄版WeChat ipa包,解壓後,得到WeChat.app,右鍵顯示包內容,開啟iterm2,cd到該目錄下。
2、
$ otool -l WeChat | grep cry //otool查詢WeChat檔案資訊,然後管道輸出以cry開頭的資訊.複製程式碼
cryptid 0 // 1代表加密演算法, 0代表未加密複製程式碼
ps:如果cryptid 1 ,證明app是經過appStore加密處理過的。此加密是對稱加密,因為資料量過大,之前我們說過非對稱加密適合小型資料加密。那麼什麼時候解密呢?是手機安裝的時候對app解密,還是在執行的時候解密呢?答案是執行的時候解密,所以在appStore上下載的app,我們每次執行的時候,都會進行解密。
3、在該資料夾下刪除外掛和帶有外掛的.app包(Watch\Plugins如果有就刪除)
4、在顯示包內容資料夾對Frameworks資料夾下的庫進行重簽名
$ codesign -fs "iPhone Developer:XXX(123A456B)" abc.framework //強制替換籤名,這裡強調一下,如果存在多個.framework都要依次強制替換籤名。複製程式碼
5、包內容下,有個叫WeChat的可執行檔案,該檔案圖示為白色則是無執行許可權,黑色則是有可執行許可權。
$ chomd +x 可執行檔案 //給檔案新增許可權複製程式碼
6、本地新建工程,(一定要是同名工程,避免在包內容資料夾下的可執行檔案衝突,同時也是為了方便),這裡新建工程是為了得到描述檔案,描述檔案不可生成,只能去請求,把新建專案在真機跑一遍,保證真機已信任該描述檔案。
7、開啟該新建工程,開啟包內容,複製描述檔案,然後貼上到微信的包內容下
7、替換BundleID,在微信(WeChat.app)的包內容資料夾下找到info.plist檔案,替換成新建工程的BundleID。
8、開啟新建工程的描述檔案、檢視描述檔案資訊
$ cd /複製程式碼
$ security cms -Di +描述檔案複製程式碼
<key>Entitlements</key>
<dict>
<key>xxxxx</key>
<array>xxxxx</array>
<true/>xxxx
<string>xxxx</string>
</dict>複製程式碼
複製<dict>下所有內容,然後新建abx.plist檔案,貼上其內容,保證格式正確。
9、通過授權檔案(Entilements)重籤.app包,注意,上面生成的abx.plist的很重要,描述檔案包含其許可權檔案。
$codesign -fs "iPhone Developer:XXX(123A456B)" --no-strict --entitlements=abx.plist WeChat.app
複製程式碼
10、回到Xcode新建專案中,command + shift + R,點選+,安裝WeChat.app。這時候會提示,是否要替換掉你剛才新建的專案(因為為了讓手機信任描述檔案,所以我們之前用真機跑過一次新建專案)。選擇替換replace。
11、至此安裝成功。回到Xcode中,點選debug,選擇attach to process,找到WeChat。點選。直到Xcode程式欄中顯示, Running WeChat on XXiPhone。成功附加,就可以lldb除錯了。
說在最後面的話。以上知識點僅是重新簽名的原理,日後還會更新利用Xcode快速重簽名以及shell指令碼重簽名。
如果我哪裡寫的不對,還希望你能校正出來,我們共同進步,如果你喜歡此文章,就動一動小手點個贊吧。