代碼簽名過程
App包上傳到AppStore的簽名過程
1、App上傳到AppStore之前已經用私鑰對App進行了簽名;
2、iPhone手機從AppStore下載App,手機會對下載下來的包用手機里面內置的公鑰進行解密校驗。
iPhone里面內置的公鑰是在操作系統里面,隨著操作系統下發的手機的
Mac電腦、蘋果服務器、蘋果手機之間的交互
1、Mac電腦通過鑰匙串->證書助理->從證書機構頒發證書生成一個CSR文件,這個文件的本質是存儲的公鑰,此操作會生成一對公鑰和私鑰,可用如下命令查看CSR文件的信息
$openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
2、將CSR文件上傳到蘋果服務器,蘋果服務器會生成一個證書,證書下發到Mac電腦和私鑰進行關聯;蘋果服務器還會將Provision profile文件也下發到Mac電腦,這個文件里面記錄了設備IDs、AppID、Entitlement權限
3、從Mac電腦運行生成的App包,里面會有源碼、MachO執行文件、App簽名信息、描述文件,其實就是用Mac電腦里面的私鑰對App進行了簽名
4、App安裝到手機,手機里面內置在操作系統里面的公鑰會對App的簽名信息進行解密校驗,通過即可安裝打開
在簽名過程中需要用到的常用命令
查看描述文件信息:
$security cms -D -i 描述文件路徑
查看APP的簽名信息
$codesign -vv -d APP路徑
查看本機所有證書
$security find-identity -v -p codesigning
查看可執行文件的加密信息!
$otool -l WeChat | grep crypt
簽名
$codesign -fs "證書" 需要簽名的文件
對三方App進行代碼重簽名
一、手動簽名
微信重簽名步驟:
1、干掉插件Plugins文件夾里面的內容;
2、Watch 直接干掉;
3、對 Frameworks 進行簽名;
$codesign -fs "證書" 需要簽名的文件
4、給可執行文件執行權限;
$chmod +x WeChat
5、拷貝Provision profile描述文件;
6、修改info.plist 的 Bundle identifier;
7、生成plist的權限文件(Entitlements.plist);
使用**$security cms -D -i 描述文件路徑**查看描述文件信息,拷貝Entitlements里面的
<dict>
<key>keychain-access-groups</key>
<array>
<string></string>
</array>
<key>get-task-allow</key>
<true/>
<key>application-identifier</key>
<string></string>
<key>com.apple.developer.team-identifier</key>
<string></string>
<key>aps-environment</key>
<string>development</string>
</dict>
8、簽名整個APP!
$codesign -fs "iPhone Developer: WenHan Li (6ZBE4C573L)" --no-strict --entitlements=en.plist WeChat.app
9、打包其實就是一個zip
$zip -ry WeChat.ipa Payload
二、利用Xcode重簽名
1、新建一個工程,然后執行build,讓Products文件夾下面的app變黑;
2、拷貝微信的app文件包到新建工程,替換新工程里面的app文件包,包名稱保持一致;
3、干掉插件Plugins文件夾里面的內容;
4、Watch 直接干掉;
5、對 Frameworks 進行簽名;
$codesign -fs "證書" 需要簽名的文件
4、給可執行文件執行權限;
$chmod +x WeChat
5、修改info.plist 的 Bundle identifier;
6、Xcode運行。
三、腳本自動化重簽名
# ${SRCROOT} 為工程文件所在的目錄
TEMP_PATH="${SRCROOT}/Temp"
#資源文件夾,放三方APP的
ASSETS_PATH="${SRCROOT}/APP"
#ipa包路徑
TARGET_IPA_PATH="${ASSETS_PATH}/*.ipa"
#新建Temp文件夾
rm -rf "$TEMP_PATH"
mkdir -p "$TEMP_PATH"
# --------------------------------------
# 1. 解壓IPA 到Temp下
unzip -oqq "$TARGET_IPA_PATH" -d "$TEMP_PATH"
# 拿到解壓的臨時APP的路徑
TEMP_APP_PATH=$(set -- "$TEMP_PATH/Payload/"*.app;echo "$1")
# 這里顯示打印一下 TEMP_APP_PATH變量
echo "TEMP_APP_PATH: $TEMP_APP_PATH"
# -------------------------------------
# 2. 把解壓出來的.app拷貝進去
#BUILT_PRODUCTS_DIR 工程生成的APP包路徑
#TARGET_NAME target名稱
TARGET_APP_PATH="$BUILT_PRODUCTS_DIR/$TARGET_NAME.app"
echo "TARGET_APP_PATH: $TARGET_APP_PATH"
rm -rf "$TARGET_APP_PATH"
mkdir -p "$TARGET_APP_PATH"
cp -rf "$TEMP_APP_PATH/" "$TARGET_APP_PATH/"
# -------------------------------------
# 3. 為了是重簽過程簡化,移走extension和watchAPP. 此外個人免費的證書沒辦法簽extension
echo "Removing AppExtensions"
rm -rf "$TARGET_APP_PATH/PlugIns"
rm -rf "$TARGET_APP_PATH/Watch"
# -------------------------------------
# 4. 更新 Info.plist 里的BundleId
# 設置 "Set :KEY Value" "目標文件路徑.plist"
/usr/libexec/PlistBuddy -c "Set :CFBundleIdentifier $PRODUCT_BUNDLE_IDENTIFIER" "$TARGET_APP_PATH/Info.plist"
# 5.給可執行文件上權限
#添加ipa二進制的執行權限,否則xcode會告知無法運行
#這個操作是要找到第三方app包里的可執行文件名稱,因為info.plist的 'Executable file' key對應的是可執行文件的名稱
#我們grep 一下,然后取最后一行, 然后以cut 命令分割,取出想要的關鍵信息。存到APP_BINARY變量里
APP_BINARY=`plutil -convert xml1 -o - $TARGET_APP_PATH/Info.plist|grep -A1 Exec|tail -n1|cut -f2 -d\>|cut -f1 -d\<`
#這個為二進制文件加上可執行權限 +X
chmod +x "$TARGET_APP_PATH/$APP_BINARY"
# -------------------------------------
# 6. 重簽第三方app Frameworks下已存在的動態庫
TARGET_APP_FRAMEWORKS_PATH="$TARGET_APP_PATH/Frameworks"
if [ -d "$TARGET_APP_FRAMEWORKS_PATH" ];
then
#遍歷出所有動態庫的路徑
for FRAMEWORK in "$TARGET_APP_FRAMEWORKS_PATH/"*
do
echo "????????????FRAMEWORK : $FRAMEWORK"
#簽名
/usr/bin/codesign --force --sign "$EXPANDED_CODE_SIGN_IDENTITY" "$FRAMEWORK"
done
fi
# ---------------------------------------------------
# 7. 注入我們編寫的動態庫
echo "開始注入"
# 需要注入的動態庫的路徑 這個路徑我就寫死了!
#INJECT_FRAMEWORK_RELATIVE_PATH="Frameworks/libHankHook.dylib"
#
## 通過工具實現注入
#yololib "$TARGET_APP_PATH/$APP_BINARY" "$INJECT_FRAMEWORK_RELATIVE_PATH"
echo "注入完成"