假如我有一个IPA,我想要换掉其证书的话。老办法是使用Xcode,使用新的证书进行打包,重新生成IPA文件。
最近偶得灵感,觉得苹果会留给我们手签IPA的方法,于是,网上找了下,并结合苹果的文档,成功修改了多个IPA的签名证书,并使用Application Loader 成功上传。下面,简单说下重签命令。
首先我们要准备三个文件,一个是IPA文件,一个是mobileprovision
文件,还有一个是知道了密码的含有私钥的p12
文件。我们先把p12
文件打开,输入密码,装载到钥匙串里面。准备工作搞定后,可以开始我们的重签之路。
第一步,解压缩你的ipa文件,使用如下命令:
$ unzip xxx.ipa
//执行完后会多出一个Payload文件夹
//后续相关操作,均操作这个文件夹
//操作完成后,会压缩该文件夹,生成IPA文件
第二步,进行Info.plist
中相关包名,版本号等信息的修改,命令如下:
$ /usr/libexec/PlistBuddy Payload/xxx.app/Info.plist (备注:敲完此命令后,再分别敲如下的每个命令)
Set :CFBundleIdentifier com.resign.test
Set :CFBundleShortVersionString 1.0.0
Set :CFBundleVersion 1
save
quit
其中 CFBundleIdentifier
、CFBundleShortVersionString
等值可参考官方链接Information Property List Key Reference
第三步,复制mobileprovision
文件到Payload
文件夹中,命令如下:
$ cp xxx.mobileprovision Payload/xxx.app/embedded.mobileprovision
//这里embedded.mobileprovision名称是固定的
第四步,加密Frameworks
中的文件,如果你的代码中使用的是 .a
库的话,此步可以忽略,因为只会生成一个可执行文件,会在第五步中进行重签。此外,如果你使用的是动态库,并且选择了static
,这里不是Frameworks
,而是一个Embedded
(类似此名字,具体未查看)。重签此部分的代码如下:
#!/bin/sh
# resign-framework
#
#
while getopts "i:" arg #选项后面的冒号表示该选项需要参数
do
case $arg in
i)
identifier=${OPTARG}
;;
?) #当有不认识的选项的时候arg为?
# exit 1
esac
done
#检查参数
if [[ x${identifier} == x ]]; then
echo "请输入证书名称,如\"iPhone Distribution......SRF3)\""
exit
fi
appFolder=""
# search app floder
for app_item in ./Payload/*.app
do
if test -d $app_item
then
appFolder=$app_item
fi
done
if [ ${appFolder}x != "x" ]; then
echo "did found app:"$appFolder
else
echo "no ipa found."
rm -rf resign.log
exit
fi
for bundle_item in ${appFolder}/Frameworks/*.framework
do
if test -d $bundle_item
then
fileName=`basename ${bundle_item}`
fileName=${fileName%%.*}
`codesign -f -s "${identifier}" ${bundle_item}/${fileName}`
fi
done
此处的代码块可以放在一个文件中,这里我使用名为resign-framework
文件保存此代码,然后在包含Payload
文件夹的目录中,调用此命令:
$ chmod 777 resign-framework
$ ./resign-framework -i "${identifier}"
//${identifier}的值改为你证书在钥匙串(Keychain Access)中的identifier,
//在钥匙串中选中你的证书,顶部以类似`iPhone Distribution:`开头的一行字符串即为"identifier"
//备注:命令中记得要带双引号
第五步,重签项目可执行文件,这里首先需要准备xxx. mobileprovision
文件的Entitlements.plist
文件,方法如下命令:
$ security cms -D -i "xxx.mobileprovision"
//使用该命令进行查看xxx.mobileprovision文件的相关内容,可以找到以Entitlements为key的字典值。
//新建一个.plist文件,将上述值复制到plist文件中。如下示例:
<?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>keychain-access-groups</key>
<array>
<string>AD9JDJKJKA.*</string>
</array>
<key>get-task-allow</key>
<false/>
<key>application-identifier</key>
<string>AD9JDJKJKA.com.resign.test</string>
<key>com.apple.developer.team-identifier</key>
<string>AD9JDJKJKA</string>
<key>aps-environment</key>
<string>production</string>
<key>beta-reports-active</key>
<true/>
</dict>
</plist>
再生成Entitlements.plist
文件后,即可进行重签:
$ codesign --entitlements Entitlements.plist -f -s "${identifier}" Payload/${appName}.app/${appName}
//${appName}用具体的名称代替,可执行文件名也为${appName}
//${identifier}仍为上方获取到的证书"identifier",注意加双引号
第六步,也是最后一步,压缩文件夹,生成新的IPA:
$ zip -qr app-resigned.ipa Payload/
至此,我们可以得到一个新的app-resigned.ipa
文件,可上传测试。
阅读此文章时,如有任何问题,可邮件至wshfor@hotmail.com
,如有IPA重签失败,请邮件附带IPA、P12文件、P12密码、mobileprovision文件。
欢迎讨论,留言。