iOS 應用簽名原理及重籤技術

1、應用簽名原理

(一)代碼簽名

  • 代碼簽名是對可執行文件或腳本進行數字簽名.用來確認軟件在簽名後未被修改或損壞的措施。和數字簽名原理同樣,只不過簽名的數據是代碼而已.
    • 一、簡單的代碼簽名
      • 1.蘋果官方生成非對稱加密的一對公私鑰,在iOS的系統中內置一個公鑰,私鑰由蘋果後臺保存;
      • 2.開發者上傳APP到AppStore時,蘋果後臺用私鑰對APP數據進行簽名(即先進行Hash獲得hash值,再用私鑰加密hash值獲得「RSAHash」);
      • 3.iOS系統下載這個APP後,用公鑰驗證這個簽名,若簽名正確,這個APP確定是由蘋果後臺認證的,而且沒有被修改過,也就達到了蘋果的需求:保證安裝的每個APP都是通過蘋果官方容許的。(公鑰解密「RSAHash」獲得hash,在對應用包進行相同算法的Hash獲得hash1,驗證兩次Hash的值是否相同);
    • 二、蘋果實際需求
      • 1.安裝包不須要上傳到App Store,能夠直接安裝到手機上.
        • 開發APP時直接真機調試安裝
        • 企業內部分發的渠道,企業證書籤名的APP也是須要順利安裝的
      • 2.蘋果爲了保證系統的安全性,又必須對安裝的APP有絕對的控制權
        • 通過蘋果容許才能夠安裝
        • 不能被濫用致使非開發APP也能被安裝

(二)雙層代碼簽名

  • 爲了實現蘋果驗證應用的一些需求,iOS簽名的複雜度也就開始增長了,蘋果給出的方案是雙層簽名.
    雙層簽名原理圖
  • iOS的雙層代碼簽名流程這裏簡單梳理一下,這也不是最終的iOS簽名原理,iOS的最終簽名在這個基礎上還要稍微加點東西。首先這裏有兩個角色,一個是iOS系統,還有一個就是咱們的Mac系統,由於iOS的APP開發環境在Mac系統下,因此這個依賴關係成爲了蘋果雙層簽名的基礎;
    • 1.蘋果本身有固定的一對公私鑰,跟以前AppStore原理同樣,私鑰在蘋果後臺,公鑰在每一個iOS系統中.這裏稱爲公鑰A,私鑰A;在Mac系統中生成非對稱加密算法的一對公鑰\私鑰(你的Xcode幫你代辦了).這裏稱爲公鑰M和私鑰M; A=Apple M = Mac
    • 2.把公鑰M以及一些你開發者的信息,傳到蘋果後臺(這個就是CSR文件);
    • 3.用蘋果後臺裏的私鑰A去簽名公鑰M。獲得一份數據包含了公鑰M以及其簽名,把這份數據稱爲證書。
    • 4.在開發時,編譯完一個APP後,用本地的私鑰M(從此你導出的P12)對這個APP 進行簽名,同時把第三步獲得的證書一塊兒打包進 APP 裏,安裝到手機上;
    • 5.在安裝時,iOS系統取得證書;
    • 6.經過系統內置的公鑰A解籤,去驗證證書的數字簽名是否正確;
    • 7.驗證證書後確保公鑰M是蘋果認證過的;
    • 8.再用公鑰M去驗證APP的簽名,這裏就間接驗證了這個APP的安裝行爲是否通過蘋果官方容許。(這裏只驗證安裝行爲,不驗證APP是否被改動,由於開發階段 APP 內容老是不斷變化的,蘋果不須要管。)

(三)描述文件

  • 描述文件(Provisioning profile)通常包括三樣東西:證書、AppID、設備。當咱們在真機運行或者打包一個項目的時候,證書用來證實咱們程序的安全性和合法性。
  • 蘋果爲了解決應用濫用的問題,因此蘋果又加了兩個限制.
    • 在蘋果後臺註冊過的設備才能夠安裝.
    • 制籤名只能針對某一個具體的APP.
  • 而且蘋果還想控制App裏面的iCloud/PUSH/後臺運行/調試器附加這些權限,因此蘋果把這些權限開關統一稱爲Entitlements(受權文件).並將這個文件放在了一個叫作Provisioning Profile(描述文件)文件中.
  • 描述文件是在AppleDevelop網站建立的(在Xcode中填上AppleID它會代辦建立),Xcode運行時會打包進入APP內. 因此咱們使用CSR申請證書時,咱們還要申請一個東西!! 就是描述文件!
  • 在開發時,編譯完一個APP後,用本地的私鑰M對這個APP進行簽名,同時把從蘋果服務器獲得的 Provisioning Profile文件打包進APP裏,文件名爲embedded.mobileprovision,把 APP 安裝到手機上.最後系統進行驗證。

2、應用重簽名

(一)codesign手動重籤

  • Xocde提供了簽名工具,codesign,咱們經過幾個命令就能夠完成重簽名。
  • 重簽名步驟:
    • 前期準備:
      • $codesign -vv -d WeChat.app 查看應用簽名信息
      • $security find-identity -v -p codesigning 列出鑰匙串裏可簽名的證書
      • $otool-l "文件名" | grep cry 查看machO文件是否加密(cryptid 0/1)
    • 1.刪除插件和帶有插件的.app包(好比Watch,PlugIns)
    • 2.對Frameworks裏面的庫進行重簽名
      • $Codesign –fs 「證書串」 文件名 強制替換籤名
    • 3.給可執行文件 +x(可執行)權限
      • $Chmod +x 可執行文件 給文件添加權限
    • 4.添加描述文件(新建工程,真機編譯獲得)
      • $security cms -D -i ../embedded.mobileprovision 查看描述文件
    • 5.替換BundleID,info.plist 文件內的BundleID修改
    • 6.經過受權文件(Entilements)重籤.app包
      • $codesign -fs 「證書串」 --no-strict --entitlements=權限文件.plist APP包
      • $Zip –ry 輸出文件 輸入文件 將輸入文件壓縮爲輸出文件
    • 7.cmd + shift + 2 直接安裝.app包,而後Attach to Process 能夠將正在運行的應用附加到Xcode上,動態調試;

(二)利用 Xode 重簽名

  • 重簽名步驟:
    • 1.新建同名工程,編譯出.app包,並替換爲須要重籤的.app包;
    • 2.刪除插件和帶有插件的.app包(好比Watch,PlugIns)
    • 3.對Frameworks裏面的庫進行重簽名
      • $Codesign –fs 「證書串」 文件名 強制替換籤名
    • 4.運行同名工程,重籤成功;
  • 注:1.非同名工程不會運行重籤包內容,machO文件不能隨便修改,包括文件名;
    • 2.斷點調試時,image list 能夠查看當前鏡像列表;

(三)SHELL腳本

  • shell是一種特殊的交互式工具,它爲用戶提供了啓動程序、管理文件系統中文件以及運行在系統上的進程的途徑。Shell通常是指命令行工具。它容許你輸入文本命令,而後解釋命令,並在內核中執行。
  • Shell腳本,也就是用各種命令預先放入到一個文本文件中,方便一次性執行的一個腳本文件

腳本執行相關文件

  • $source FileName算法

    • 意思:在當前shell環境中讀取並執行FileName中的命令
    • 特色:
      • 命令能夠強行讓一個腳本去當即影響當前的環境(通常用於加載配置文件)。
      • 命令會強制執行腳本中的所有命令,而忽略文件的權限。
  • $bash/zsh FileNameshell

    • 意思:從新創建一個子shell,在子shell中執行腳本里面的句子。
  • $./FileName安全

    • 意思:讀取並執行文件中的命令。但有一個前提,腳本文件須要有可執行權限。

(四)用戶組&文件權限

  • Unix和Linux都是多用戶、多任務的系統,因此這樣的系統裏面就擁有了用戶、組的概念。那麼一樣文件的權限也就有相應的所屬用戶和所屬組了。
一、Mac 文件屬性

二、文件類型與權限(permission)
  • 文件類型:(常見)
    • [d] 目錄(文件夾)(directory)
    • [-] 文件
  • 文件權限:
    • [r]:read,讀 [w]:write,寫 [x]:execute,執行。
    • 注意:這三個權限的位置不會變,依次是rwx,出現減號[-]在對應位置,表明沒有此權限。
    • 一個文件的完整權限,總共分爲三組:
      • 第一組:文件全部者的權限
      • 第二組:這一組其餘用戶的權限
      • 第三組:非本組用戶的權限
三、改變權限:chmod
  • 文件權限的改變使用chmod命令。設置方法有兩種:數字類型改變符號類型改變
    • 因爲文件權限分爲三種身份:[user][group][other]
    • 三個權限:[read] [write] [execute]
  • 1.數字類型:
    • 各個權限數字對照:r:4 w:2 x:1
    • 若是一個文件權限爲 [–rwxr-xr-x ]
      • User : 4+2+1 = 7
      • Group: 4+0+1 = 5
      • Other: 4+0+1 = 5
      • 命令:chmod 755 文件名
    • 各類身份對應權限計算
  • 2.符號類型:chmod [u、g、o、a][+(加入)/-(除去)/=(設置)][r、w、x] 文件名稱
    • eg. chmod a-w README.md

(五)shell腳本自動重簽名

一、Xcode 添加執行腳本的入口
二、shell文件準備
# ${SRCROOT} 它是工程文件所在的目錄
TEMP_PATH="${SRCROOT}/Temp"
#資源文件夾,咱們提早在工程目錄下新建一個APP文件夾,裏面放ipa包
ASSETS_PATH="${SRCROOT}/APP"
#目標ipa包路徑
TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa"
#清空Temp文件夾
rm -rf "${SRCROOT}/Temp"
mkdir -p "${SRCROOT}/Temp"

#----------------------------------------
# 1. 解壓IPA到Temp下
unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
# 拿到解壓的臨時的APP的路徑
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# echo "路徑是:$TEMP_APP_PATH"

#----------------------------------------
# 2. 將解壓出來的.app拷貝進入工程下
# BUILT_PRODUCTS_DIR 工程生成的APP包的路徑
# TARGET_NAME target名稱
TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
echo "app路徑:$TARGET_APP_PATH"

rm -rf "$TARGET_APP_PATH"
mkdir -p "$TARGET_APP_PATH"
cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH"

#----------------------------------------
# 3. 刪除extension和WatchAPP.我的證書無法簽名Extention
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"

#----------------------------------------
# 4. 更新info.plist文件 CFBundleIdentifier
# 設置:"Set : KEY Value" "目標文件路徑"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"

#----------------------------------------
# 5. 給MachO文件上執行權限
# 拿到MachO文件的路徑WeChat
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#上可執行權限
chmod +x "$TARGET_APP_PATH/$APP_BINARY"

#----------------------------------------
# 6. 重簽名第三方 FrameWorks
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do

#簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi

#注入
yololib "$TARGET_APP_PATH/$APP_BINARY" "Frameworks/HankHook.framework/HankHook"
複製代碼
相關文章
相關標籤/搜索