App簽名二三事

1、概述

相比於Android系統,iOS對下載到設備中的軟件有比較嚴格的限制;絕大多數人,只會從AppStore下載App,這也杜絕了不少安全隱患;可是對於iOS開發者來講,須要搞明白不少事情(如:iOS App的簽名原理),甚至須要作一些小動做(如重簽名)來達到本身(友好的)目的。git

一、基礎概念

  • 摘要算法:把一個任意長度的字節串映射 爲必定長度的十六進制的數字串;這個數字串稱爲哈希值。常見有:MD五、SHA一、SHA25六、SHA512等算法

  • 對稱加密:加密和解密使用相同密鑰,常見有:DES算法、3DES算法和AES算法等;shell

  • 非對稱加密:加密和解密使用不一樣密鑰的加密算法,用公鑰加密的數據,要用私鑰才能解密,用私鑰加密的數據,要用公鑰才能解密;經常使用加密算法有:RSA、Elgamal、揹包算法等;安全

  • 數字簽名(digital signature):bash

    • 是非對稱加密與摘要算法的結合,用於驗證數據的完整性及不可抵賴性;
    • 發送方對數據計算出摘要信息,而後用發送方私鑰加密,獲得摘要密文,這就是數字簽名;
    • 接收方收到後,利用發送方的公鑰和非對稱算法從數字簽名中獲取摘要明文;根據原始內容計算出摘要 和 解密出來的摘要明文進行對比;不一致,說明內容被篡改 or 收到內容不是指定發送方;
  • 數字證書(digital certificate):app

    • 數字證書數爲了保護髮送方公鑰不被僞造而發明的,引入證書中心(Certificate Authority,CA)概念,CA用本身的私鑰,對發送方的公鑰和一些相關信息一塊兒加密,生成"數字證書"(Digital Certificate)。
    • CA的數字證書中有:簽發者、證書用途、發送方公鑰、發送方非對稱加密算法、發送方HASH算法和到期時間等
    • 接收方拿到數字證書後,先從數字證書中解密出發送方公鑰(用的是CA的公鑰和CA解密算法);而後根據發送方公鑰去解密數字證書,獲得摘要;最後比對原始數據計算出的摘要是否一致。
    • CA是第三方機構,CA公鑰是公開的,接收方能夠跟別人比對(好比網上查),所以不可能僞造。而發送方公鑰,是接收方從數字證書中得到的。
    • 數字證書在https協議實現中有重要應用

二、簽名相關的幾個概念

名稱 做用
證書(cer) 內容是公鑰或私鑰,由其餘機構對其簽名組成的數據包。
Entitlements 包含了 App 權限開關列表
CertificateSigningRequest 本地公鑰
p12 本地私鑰,能夠導入到其餘電腦。
Provisioning Profile 包含了 證書 / Entitlements 等數據,並由蘋果後臺私鑰簽名的數據包。

三、iOS包渠道及其簽名機制

  • iOS設備上App的渠道粗分有AppStore渠道非AppStore渠道,非AppStore包有:Testflight內測包、In-House 企業內部分發包、Ad-Hoc(至關於企業分發的限制版,限制安裝設備梳理)和Xcode調試安裝;(越獄包不在此範圍)。ide

  • AppleStore中渠道包簽名驗證工具

    • 蘋果官方生成一對公私鑰,在 iOS 系統中內置一個公鑰,私鑰由蘋果後臺保存。
    • App 上傳到 App Store 時,蘋果後臺用私鑰對 App 數據進行簽名(計算出摘要,再私鑰加密);
    • iOS 下載這個 App 後,用公鑰驗證這個簽名,若是簽名正確則這個 App 確定是由蘋果後臺認證的,而且沒有被修改或損壞。
  • 非AppleStore渠道包的簽名驗證須要使用雙重簽名機制,保證不被濫用。post

2、雙重簽名機制

一、簡介

  • 使用兩對公私鑰作加密驗證,分別是 Mac本地的一對公私鑰Apple提供的一對公私鑰(私鑰在蘋果後臺,公鑰在每一個 iOS 設備上)。
  • 雙重簽名的存在是爲了知足:
    • App 須要通過蘋果容許才能安裝;
    • 在 Apple 後臺中註冊過的設備才能安裝,好比在 TestFlight 內測、真機調試模式下;
    • 限制簽名只能對應惟一的 App;

二、重要概念

  • Mac 上執行鑰匙串訪問 -> 證書助理 -> 從證書頒發機構請求證書...,就會在Mac本地生成了一對公私鑰,導出的 CSR 文件(CertificateSigningRequest.certSigningRequest)就是 Mac 公;測試

  • CSR 文件上傳到蘋果後臺,蘋果用Apple私鑰對其簽名,並生成一份包含Mac公鑰信息 和 蘋果簽名信息的開發/發佈證書cer

  • 當咱們將cer下載並安裝到Mac後,keychain會把CertificateSigningRequest和cer證書關聯起來。在鑰匙串中找到該證書,能夠導出Mac私鑰(.p12 文件)

  • 在蘋果後臺須要配置AppID、可用設備IDs(企業證書不須要) 和 Entitlements(App 權限開關列表),對這些額外信息 和 cer證書使用Apple私鑰簽名,最後蘋果將證書 + 額外信息 + 簽名組成一個Provisioning Profile文件(後綴mobileprovision),可下載到Mac上。

    Provisioning Profile文件又被成爲描述文件,安裝好後,存放在~/Library/MobileDevice/Provisioning Profiles路徑下
    複製代碼

三、App簽名和驗證

雙簽名和驗證

  • 在Mac上編譯完一個App後,Mac先用Mac私鑰對App簽名,並將Provisioning Profile文件也打包到App中,文件名爲embedded.mobileprovision

  • iOS系統安裝App時,蘋果經過內置在手機中的Apple公鑰驗證embedded.mobileprovision中的簽名是否正確,接着驗證證書中的簽名是否正確

  • 在確保embedded.mobileprovision裏的數據都是蘋果受權之後,就從裏面取出數據,作後續各類驗證,包括

    • 用Mac公鑰驗證App簽名
    • 驗證設備 ID 是否在 ID 列表上
    • 驗證證書是否過時
    • 驗證AppID 是否對應得上
    • 驗證權限開關是否跟 APP 裏的 Entitlements 對應等等。
  • 若是別的 Mac 也要編譯後簽名這個 App,就必需要獲取申請生成cer證書那個Mac機器上的私鑰;這個比較簡單,只須要在那臺機器的鑰匙串中找到cer證書,而後右鍵導出Mac私鑰(.p12 文件);

  • 簡單來講,要在別人設備上成功編譯成功並將App安裝到設備中,須要cer證書導出的**.p12文件和Provisioning Profile文件**(描述文件)

四、補充

  • 雙層代碼簽名是針對開發測試包、In-House 企業簽名、Ad-Hoc 包爲例的簽名和驗證的流程,只是企業簽名不限制安裝的設備數,所以描述文件中不會有設備列表,而是一條 ProvisionsAllDevices 記錄。
  • 從 App Store 上下載的安裝包,裏面是沒有描述文件的,但上架以前仍是要配置證書、PP 文件,由於 App ID 和權限的檢驗仍是須要作的。但 App 上傳到 AppStore 之後就跟 PP 文件沒有關係了,因此咱們能夠理解爲 App Store 上包的簽名驗證採用就是前面說的最簡單的簽名方式,Apple 後臺直接用私鑰簽名 App 就能夠了。

3、App重簽名

一、概述

  • 重簽名本質是將已發佈/未發佈的包從新簽名爲本身的證書和簽名,關鍵點是替換ipa內的證書描述文件
  • 使用codesign工具

二、重簽名方案

  • 查看ipa包是否加殼,只有未加殼的包才能夠重簽名。

    otool -l app_name.app/app_name | grep crypt
     # 輸出cryptid爲0表明已經砸殼,即解密,爲1或者2表示以第1類或者第2類加密方案加密。
    複製代碼
  • 查看本地證書列表並記錄下要用來簽名的證書名,例如」iPhone Distribution: XXXXX (XXX)」

    security find-identity -v -p codesigning
    # 輸出有效的證書列表
    複製代碼
  • 建立一個和App同名的工程,從上步獲得有效證書列表中,選擇一個,編譯後生成新App;將這個新App裏embedded.mobileprovision文件取出替換iap包中的文件。

  • 刪除ipa包內部不能被重簽名的插件(PlugIns文件夾 和 Watch文件夾)

  • 將ipa包內的全部Framework中Mach-O文件重簽名(Frameworks目錄下有Framework)

# 命令參考
codesign -fs [證書名稱] [要簽名的文件]
 #若是沒有權限,執行chmod +x app_name.app/app_name 給Mach-O文件添加可執行權限
#Frameworks文件夾裏面的.framework本質仍是文件夾,真正要重籤的是.framework裏面的MachO可執行文件
複製代碼
  • 將ipa包內info.plist的BundleId修修改成新App對應的的BundleId

  • 用命令查看embedded.mobileprovision文件,找到其中的entitlements字段,而且複製entitlements字段和其中的內容。

    security cms -D -i 「embedded文件路徑」
    複製代碼
  • 新建entitlements.plist文件,將複製內容拷貝到文件中,而後將entitlements.plist複製到ipa的同級目錄下。

  • 對App進行重簽名,並壓縮成新的ipa包

    # 重簽名
    $ codesign -fs "iPhone Distribution: XXXXX (XXX)" --no-strict --entitlements=entitlements.plist
    
    // --no-strict 不嚴謹的 
    // --entitlements=entitlements.plist權限所在文件是entitlements.plist
    codesign -fs 簽名證書 --no-strict --entitlements=entitlements.plist app_name.app
     # 壓縮ipa包
    $ zip -r 「輸出的文件名(.ipa)」 Payload/
    複製代碼
  • 將ipa包安裝到手機,若能同時存在兩個應用且能正常運行則表示重簽名成功。

三、防止App被重簽名辦法

  • 校驗描述文件信息:在啓動時校驗描述文件信息與打包時是否一致。例如判斷組織單位: 先記錄證書中的組織單位信息。
  • sysctl檢測是否被調試,具體可見iOS安全防禦之重簽名防禦和sysctl反調

四、目的

  • 對於大多數iOS開發,瞭解App簽名原理,知道要對App作防止重簽名的保護便可。
  • 本人並不是從事越獄安全工做;使用重簽名,主要是爲了讓測試包能夠支持IAP測試,搞過IAP的同窗應該明白IAP測試中的痛點: 使用TestFlight or ad-hoc包測試的效率真的會把人逼瘋,企業內測又不支持[坑]

歷史文章

早年簡單瞭解過加密,混淆之類的事情,具體能夠看以前文章

淺談數據加密

淺談AES

淺談代碼混淆

參考文章

代碼簽名探析

iOS App 簽名的原理

iOS應用安全3 -- APP重簽名

相關文章
相關標籤/搜索