在了解代码重签名之前,可能我们需要先了解什么是代码签名.
一 什么是代码签名:
代码签名是指的对可执行文件进行数字签名,以防止软件在网上发布流传过程中被篡改或者缺损,它实质上跟数字签名一样,只不过不同的是代码签名签名的是代码而已.
二 苹果双层代码签名原理:
场景:我们回顾下,在iOS系统出现之前,windows macOS 等系统盗版软件猖獗,病毒肆虐,各种软件通过后门未经要不过户许可就静默加载进我们的设备中.这个时候苹果想解决这个问题,怎么办?
我们想到的是通过RSA公私钥,苹果服务器备有私钥,我们的iOS系统备有公钥,只有经过苹果服务器认证的软件在通过私钥签名后才能被许可为合法软件,而我们的设备在下载软件时候需要验证签名,因为密钥匹配原因,通过匹配的则是合法软件才能许可安装.这样看来似乎能够满足需求.
但是有一个问题,我们的开发者怎么办?我们的开发者在开发期间,是无法通过app store进行下载的,那么也谈不上签名,如何能够让我们的设备也能够正常安装?
这个时候苹果公司就提出了一个双层代码签名的解决方案.
双层代码签名:
1.首先我们的Mac电脑有一个公钥,当我们的开发人员需要开发APP时候,通过CSR证书申请文件向苹果服务器请求证书,苹果服务器通过自己的私钥A对其进行签名.并返回给我们的开发人员描述文件(内含设备IDs,AppID,权限文件),在这个文件中还有苹果服务器签名认证的证书(内含公钥和签名).开发人员将描述文件载入Xcode中即可进行app的开发,同时也在钥匙串中获取到与之对应的私钥(也就是P12文件).我们将处于Mac电脑中的公私钥称为公钥M,私钥M.
2.当开发人员在开发完APP后,在进行真机调试时,通过已经持有的私钥M对可执行文件进行代码签名,同时将已经持有的对应的描述文件以及代码一起打包安装在我们的设备中.
3.我们的iOS系统内置有与苹果服务器对应的公钥A,当它需要安装app时候,此时会将自身的公钥A去验证描述文件中被苹果服务器签名的证书.如果验证通过,取出证书中的公钥M(这个过程,是验证是否是通过苹果服务器许可的下载方式下载的合法app).在拿到公钥M后,再用其验证应用可执行文件的代码签名,如果匹配,则进行安装(这个过程是验证是否是可信任的开发者.也是版权保护手段).
4,在APP安装进我们的iOS系统时候,还会去验证描述文件,它是在我们app包内一个文件名为embedded.mobileprovision的东西,我们的系统会去验证这个文件,以此知道这个app拥有哪些权限,当前设备是否允许安装.这也是为什么我们开发时候需要添加设备.
三 iOS代码重签名:
我们的Xcode内置的CodeSign工具可以对代码进行签名:
签名命令:
$Codesign -fs "证书串" 文件名
手动签名步骤:
1.首先我们需要准备需要重签名的ipa包.这里推荐使用PP助手(当然也可以去其他的第三方助手下载),因为我们需要下载的是已经越狱的应用,在PP助手上下载的应用是已经越狱的.如果下载的ipa包是非越狱的应用,那么签名之前需要对应用先行砸壳.
2.将App包解压,并删除个人账户无法签名的部分(比如插件工具,Watch文件),当然如果你是用企业证书那么可以不做这步.
3.重签名应用所有的Framework.值得注意的是这里的证书需要与空项目里的描述文件中的开发证书一致,否则会出现签名信息显示无法获取的情况.
4.将应用包内的info.plist的Bundle Identifier 修改成自己起的空项目包名.
5.重签应用包.将空项目的描述文件拷贝到需要重签名的包内,并提取出里面的权限键值对放在一个新的plist文件中(需要用这个权限文件去签名)放在项目根目录中.
6.签名app包.使用我们上述得到的权限文件签名需要重签名的.app文件
•$codesign -fs “证书串” --no-strict --entitlements=权限文件.plist APP包
7.将重签名的.app包 重新打包成新的ipa包
•$Zip –ry输出文件输入文件 将输入文件压缩为输出文件
自此我们就手动重签名完应用了.我们可以将这个ipa包通过Xcode的Device去进行装载.装载完成后 我们就可以运行工程,并进行附加调试.
Shell脚本重签名:
1.在Xcode中添加一个脚本执行项.
这里的SRCROOT就是项目根目录,这条脚本命令就是执行这个目录下的sign.sh脚本.
2.编写sign.sh脚本.
具体签名逻辑实现过程其实跟手动签名差不多,具体步骤和注解可以直接看图,当然这里的逻辑还比较粗糙,细节方面还需要慢慢继续改进.
我们在使用这个脚本的时候,只需要在项目根目录下建立一个名为APP的文件夹,里面放入已经越狱的ipa应用,那么在项目下只要引入这个脚本并把脚本文件放入根目录,就可以在运行的时候自动重新签名并可以直接调试.
该脚本文件仅供学习交流使用.谢谢大家!