iOS ipa重簽名 (個(gè)人版、企業(yè)版APP均可)
本文的實(shí)現(xiàn)方案包括腳本參照的是簡(jiǎn)書(shū)的一篇文章ios打渠道包,根據(jù)我項(xiàng)目中的實(shí)際情況做了修改,在此記錄一下整個(gè)實(shí)現(xiàn)過(guò)程。
重簽名:可以讓用個(gè)人開(kāi)發(fā)者賬號(hào)打出來(lái)的包,不用上架Appstore即可將其安裝到iOS設(shè)備上(前提條件是你得有一個(gè)開(kāi)發(fā)者證書(shū))。
[圖片上傳中...(1.jpg-1ff4c-1542965152845-0)]
風(fēng)險(xiǎn)提示:這種重簽名方法僅供個(gè)人有興趣的開(kāi)發(fā)者去玩玩,不提倡用于商用,提倡使用Appstore上傳發(fā)布到你的應(yīng)用,重簽名只能算是黑科技,蘋果所不提倡的東西,如果APP使用量過(guò)大的話,企業(yè)證書(shū)有被封停的風(fēng)險(xiǎn)。當(dāng)然,如果你使用的是個(gè)人開(kāi)發(fā)者賬號(hào),則只能在添加了UUID的設(shè)備上面安裝
蘋果在iOS8.1.3系統(tǒng)以后加強(qiáng)了對(duì)ipa安裝包簽名的驗(yàn)證,主要區(qū)別在于ipa唯一標(biāo)識(shí)在原有Bundle Identifier的基礎(chǔ)上增加了證書(shū)ID,也就說(shuō)安裝包和手機(jī)上已安裝APP的Bundle Identifier即使一致,如果兩者簽名的證書(shū)ID不相同,那么安裝包也無(wú)法正常安裝。
圖中方框里字符串就是證書(shū)ID(鑰匙串中我的證書(shū)),升級(jí)后的ipa標(biāo)識(shí)就是證書(shū)ID+BundleID,只有兩者完全匹配,安裝包才能覆蓋安裝,否則就會(huì)提示安裝失敗。解決辦法就是卸載安裝包,重新安裝!
如果這個(gè)地方找不到證書(shū)ID,可登錄到蘋果開(kāi)發(fā)者中心https://developer.apple.com,memberCenter,點(diǎn)擊certificates,identifier&Profiles,再點(diǎn)擊identifier中的App IDs點(diǎn)擊某個(gè)AppId(因?yàn)樽C書(shū)ID是唯一的,所以選哪個(gè)APPID都是一樣的)
其中Prefix就是證書(shū)ID
目前,重簽名主要用于企業(yè)證書(shū)重簽名個(gè)人證書(shū)發(fā)布的ipa包,包括各種助手及企業(yè)內(nèi)測(cè)包的發(fā)布等。在重簽名前,讓我們先看看一個(gè)完整的ipa包有哪些與證書(shū)相關(guān)的東西!將ipa包后綴名改為zip,解壓之后,會(huì)發(fā)現(xiàn)一個(gè)文件夾Payload(如果是個(gè)人證書(shū)打包還會(huì)包含Symbols文件夾),payload文件夾下面的XXX.app文件夾中有_CodeSignature簽名文件夾和embedded.mobileprovision證書(shū)配置文件以及其他資源文件。重簽名只關(guān)注這兩個(gè)文件即可。
[圖片上傳中...(4.jpg-6293cb-1542965284384-0)]
_CodeSignature -> ipa包簽名文件
embedded.mobileprovision -> 證書(shū)配置文件
so,替換上面兩個(gè)文件就解決了ipa重簽名的主要問(wèn)題。
替換_CodeSignature里面的簽名文件需要用到一個(gè)文件entitlements.plist的授權(quán)文件, 所以我們要?jiǎng)?chuàng)建一個(gè)entitlements.plist文件( 這里我沒(méi)有找到, 我就重新創(chuàng)建了一個(gè), 后面說(shuō))
這里開(kāi)始正文
首先,我的需求是,在手上已有ipa安裝包,也就是母包的情況下,修改母包中的某個(gè)文件中作為渠道號(hào)的值,生成新的ipa安裝包,也就是帶有渠道號(hào)的渠道包。
這是已經(jīng)打包成功導(dǎo)出的 ipa包:
ipa包,我們可以視為一個(gè)壓縮包,使用解壓工具對(duì)其解壓可以得到一個(gè)名叫Payload的文件夾:
Payload文件夾中是一個(gè).app文件(可能看不到 .app 的尾巴),右鍵顯示包內(nèi)容可以看到其中的文件:
其中的DChannel.plist文件就是在母包打包之前在Xcode工程中新建的,用于存儲(chǔ)渠道號(hào)等信息,我在這個(gè)plist文件中設(shè)置了叫Channel的字段,可以隨意給一個(gè)默認(rèn)值。之后我們?cè)诮o母包打渠道號(hào)時(shí),就是要修改plist文件中的Channel值,修改后重新壓縮Payload文件夾生成渠道包,此時(shí)渠道包運(yùn)行后,程序中獲取的Channel值就變成了對(duì)應(yīng)的渠道號(hào)。
下面是操作步驟:
準(zhǔn)備文件:
1. entitlements.plist: [圖片上傳中...(9.jpg-7231e0-1542965517810-0)]
- 注意:get-task-allow一定要填NO(false)(否則安裝一定失敗),還有bundleID一定要與新的embedded.mobileprovision相對(duì)應(yīng),不然會(huì)導(dǎo)致簽名失敗。
<?xml version="1.0" encoding="UTF-8"?>
<!DOCTYPE plist PUBLIC "-//Apple//DTD PLIST 1.0//EN" "http://www.apple.com/DTDs/PropertyList-1.0.dtd">
<plist version="1.0">
<dict>
<key>application-identifier</key>
<string>xxxxxxxxxx.com.xxx.xxx</string>
<key>com.apple.developer.team-identifier</key>
<string>xxxxxxxxxx</string>
<key>get-task-allow</key>
<false/>
<key>keychain-access-groups</key>
<array>
<string>xxxxxxxxxx.com.xxx.xxx</string>
</array>
</dict>
</plist>
2.ChannelPackage.sh:
#!/bin/bash
# 1. 這里面的包名需要傳過(guò)來(lái), 作為一個(gè)工具類
# 2. 修改的取到標(biāo)識(shí)也可以作為參數(shù)傳進(jìn)來(lái), 我這里直接寫死了
# 3. 這里的 Dchannel.plist 文件我這里是我區(qū)分渠道的標(biāo)識(shí), 修改為你需要的
# 4. 使用的話, 需要修改 shell 腳本的地方,① Dchannel.plist ② ChannelID ③ Distribution證書(shū)
# 5. 成功了, 上傳 fir 或者蒲公英測(cè)試一把吧
# 6. 還是不懂的話 qq:249804175 直接滴滴我
# 輸入的包名
name=$1
# $1 就是傳進(jìn)來(lái)的第一個(gè)參數(shù) $2就是第二個(gè)參數(shù)
#echo 是打印的意思
echo "---ahh---"
echo ${name}
appName="${name}.app"
echo ${appName}
plistBuddy="/usr/libexec/PlistBuddy"
#configName="channel.plist"
configName="Payload/${appName}/DChannel.plist"
configNameNew="Payload"
ipa="${name}.ipa"
# 打好包后輸出的文件夾名字
outUpdateAppDir="OutApps"
# 獲取當(dāng)前目錄,并切換過(guò)去
currDir=${PWD}
echo ${currDir}
cd "${currDir}"
echo "-----${currDir}"
# 生成日志目錄
#mkdir log
rm -rf Payload
#解壓縮
unzip -o -q ${ipa} #>> log/unzipUpdateApp.log
#echo `ls Payload`
# 刪除舊的文件,重新生成
rm -rf "${outUpdateAppDir}"
mkdir "${outUpdateAppDir}"
echo "------------------------開(kāi)始打包程序------------------------"
#echo ""
# 渠道列表文件開(kāi)始打包
#for line in $(cat TargetChanelList.txt)
#循環(huán)數(shù)組,批量打包時(shí)需要修改的渠道號(hào)和渠道Id ("1174" "1173")
# 這里的參數(shù)可以從外面直接傳過(guò)來(lái),
ChannelID=("111" "222" "333")
echo ${#ChannelID[@]}
for ((i=0;i<${#ChannelID[@]};i++))
do
#echo是輸出命令,可以忽略
echo "........正在打包渠道號(hào):${ChannelID[$i]}"
# cd Payload/${appName}
# 設(shè)置Channel.plist
echo "-----1----${PWD}"
#修改
$plistBuddy -c "set :Channel ${ChannelID[$i]}" ${configName}
echo "-----2----${PWD}"
rm -rf Payload/${appName}/_CodeSignature
#cp AdHoc配置文件 替換 Payload/${appName}文件下的embedded.mobileprovision
cp embedded.mobileprovision "Payload/${appName}/embedded.mobileprovision"
# ipa包簽名: codesign -f -s "iPhone Distribution: Distribution證書(shū)名字,打開(kāi)鑰匙串可以看到" --entitlements "Entitlements.plist" "Payload/${appName}"
codesign -f -s "iPhone Distribution: Distribution證書(shū)名字,打開(kāi)鑰匙串可以看到" --entitlements entitlements.plist Payload/DEMO.app
#Payload/Demo.app: replacing existing signature :這個(gè)時(shí)候是已經(jīng)OK
zip -rq "${outUpdateAppDir}/${ChannelID[$i]}.ipa" "Payload"
echo "........打包已完成"
done
echo "------------------------程序打包已結(jié)束------------------------"