为什么要研究重签名问题?
将程序打包成ipa包后,ipa包中会包括Provisioning Profile和_CodeSignature等文件,里面包括了对整个ipa的签名信息。一旦改动ipa中的任何内容,例如增加一个头文件,签名就会失效,导致ipa无法安装。(貌似改变Info.plist是不影响的)
因此,如果要通过修改ipa包中的内容来得到篡改信息或注入代码的话,就需要解决ipa包的重签名问题。
准备
在重签名之前要做一些准备工作。
1.首先要下载并安装Xcode,里面有个codesign_allocate程序,在安装时/usr/bin中会多一个codesign的程序,该程序用于ipa包的签名。
2.企业证书的Certificate文件,私钥文件,Provisioning Profile文件等。注意企业证书一定要是iOS Distribution的类型,不能是iOS Development。其它详细设置,如In-House等参见http://beyondvincent.com/blog/2014/07/30/provision-ios-ipa-app-for-in-house-enterprise-distribution/
重签名步骤
1.解压ipa
解压ipa得到Payload/[App name].bundle,打开bundle。
2.删除旧的ipa签名信息
删除bundle中的_CodeSignature文件夹,也就是删除之前ipa的签名信息。
3.更换证书
将bundle中旧的Provisioning Profile删除,用我们自己的企业证书的Provisioning Profile替代。
注意,要将ipa包中我们的企业证书改名为embedded.mobileprovision。
4.修改bundle内容
此时我们可以尽情地修改bundle中的内容,例如添加一个动态库,删除一张图片等。
5.重新签名
在完成bundle内容的修改后,需要通过/usr/bin/codesign程序重新签名,命令如下:
/usr/bin/codesign -f -s "iPhone Distribution: YourCompanyName" --resource-rules Payload/ MYAPP.app/ResourceRules.plist Payload/ MYAPP.app
其中iPhone Distribution可以从钥匙串访问中获取,就是企业证书的名字,例如下面的"iPhone Distribution:XXXXXXXXXX":
具体的命令示例:
codesign -f -s "iPhone Developer: XXXXXXXXXX" --resource-rules Payload/NdCP_Game_Demo.app/ResourceRules.plist Payload/NdCP_Game_Demo.app
这条命令的意思是:使用keychain中"iPhone Developer: XXXXXXXXXX"标识的证书,根据Payload/NdCP_Game_Demo.app/ResourceRules.plist文件中的规则进行签名,如果ipa包中已经存在签名,那么将被替换,该过程生成的_CodeSignature目录将存放在Payload/NdCP_Game_Demo.app目录下。
在命令执行后,在bundle中会生成一个新的_CodeSignature目录,里面包含了新的签名信息。
6.重新打包成ipa
在完成上述工作后,可以生成新的ipa进行发布。示例命令如下:
zip -r ResignTest.ipa Payload # 注意Payload后面不能有“/”
7.发布
经过打包发布测试,得出结论:对修改了ipa包内容和其中的签名后,重签名的ipa文件可以在非越狱设备和越狱设备上成功安装。注意,是通过带有SSL证书的网站和Apple系统安装的(企业内部分发程序),不是通过PP助手那样的第三方工具安装的。
参考资料
http://www.cocoachina.com/bbs/simple/?t181236.html
http://www.169it.com/article/15588355475122308384.html
附录
1.codesign
在帮助文档中:
codesign -- Create and manipulate code signatures
codesign的选项:
-f, --force When signing, causes codesign to replace any existing signature on the path(s) given. Without this option, existing signatures will not be replaced, and the signing operation fails. -s, --sign identity Sign the code at the path(s) given using this identity. See SIGNING IDENTITIES below. --resource-rules filename During signing, this option overrides the default rules for identifying and collecting bundle resources and nested code to be sealed into the signature. The argument is the path to a property list (plist) file containing scanning and qualification instructions. See the code signing documentation for details.
其使用方法如下:
Usage: codesign -s identity [-fv*] [-o flags] [-r reqs] [-i ident] path ... # sign codesign -v [-v*] [-R testreq] path|[+]pid ... # verify codesign -d [options] path ... # display contents codesign -h pid ... # display hosting paths