在iOS系统出来以前,主流的操做系统(Mac或者Windows)软件随便从哪里下载都能安装,运行,系统安全存在隐患,盗版软件,病毒入侵,静默安装等等问题,苹果但愿iOS的系统上不会出现这样的问题,就要保证每个安装到iOS系统上的APP都是通过苹果官方容许的,那么苹果是如何作到的呢?ios
苹果服务器生成一对RSA的公钥A和私钥A,私钥A服务器保存,公钥A分给每一台iOS设备,服务器对每一个APP使用私钥A签名,iOS设备在安装APP的时候,使用内置的公钥A对APP进行验证,只有经过验证了的APP才容许安装,这样就能够保证安装的APP都是通过苹果容许的了;git
或许苹果在没有开放App Store给广大开发者的时候,这样简单的代码签名就够了;可是后来随着苹果对App Store的开放,我的开发者,公司开发者随时都须要链接真机调试开发APP;还有企业开发者须要在企业内部分发APP,而不须要上传App Store,须要作到开放这些方式安装APP,同时还要保证这些安装行为是可控的,那么上面所讲简单的代码签名就没法实现了github
咱们分析一下苹果对于APP安装的需求:shell
为了实现这些需求,iOS代码签名的复杂度也就增长了,苹果实现的方案是双重签名缓存
除了上传到App Store的APP能够下载安装以外,开发人员也能够直接使用Mac系统将开发中的APP安装到iPhone手机上,可是这个安装行为也是须要苹果容许的;安全
作过iOS开发的同窗应该知道,当须要将Xcode开发的APP安装到真机上的时候,Xcode会在Signing & Capabilities下给出红色的错误,提示开发者Signing for "xxx" requires a development team.
意思签名你开发的APP须要一个开发团队,这个开发团队就是由证书(Signing Certificate)和描述配置文件(Provisioning Profile)组成的;关于描述配置文件,咱们放在后面再说;那这个证书(Signing Certificate)是怎么来的呢?服务器
当咱们使用Mac上的Xcode安装APP的时候,Xcode会在咱们的Mac电脑上生成一对RSA的公钥M和私钥M(M=Mac);而后将公钥M经过CSR(Certificate Signing Request)文件向苹果服务器请求签名;微信
以前说了苹果服务器和iOS系统之间是有一对公钥A和私钥A的(A=Apple)markdown
苹果服务器收到CSR文件以后,会使用本身的私钥A对公钥M的hash进行签名,这样公钥M和通过苹果服务器私钥A签名过的hash组成一份文件返回给Mac系统了,这份文件就叫作证书;咱们打开Mac系统上的钥匙串访问就能看到许多的证书,点击签名的箭头还能看到对应的私钥M;app
在开发过程当中,编译完一个APP后,用本地的私钥M(或者别人给你的p12)对这个APP进行签名,同时把上一步获得的证书一块儿打包进APP里,安装到手机上
在安装APP时,iOS系统获取APP包里的证书,经过iOS系统内置的公钥A,去验证这个证书签名是否正确
验证经过以后,就说明证书里的公钥M是没有通过篡改的,再使用这个公钥M去验证APP的签名,若是经过了验证就说明APP也是没有被篡改过,能够安装的
有了上面的过程,已经能够保证开发者的认证,和程序的安全性了。可是,要知道iOS的程序,主要渠道是要经过APP Store才能分发到用户设备的,若是只有上述的过程,那岂不是只要申请了一个证书,就能够安装到全部iOS设备了?描述文件的做用就来了
描述文件(Provisioning profile)通常包括三样东西:证书、App ID、设备。当咱们在真机运行或者打包一个项目的时候,证书用来证实咱们程序的安全性和合法性。
苹果为了解决应用滥用的问题,因此苹果又加了两个限制:
而且苹果还想控制App里面的iCloud/PUSH/后台运行/调试器附加这些权限,因此苹果把这些权限开关统一称为Entitlements(受权文件).并将这个文件放在了一个叫作Provisioning Profile(描述文件)文件中.
描述文件的存放路径:~/Library/MobileDevice/Provisioning Profiles
描述文件是在AppleDeveloper网站建立的(在Xcode中填上AppleID它会代办建立),Xcode运行时会打包进入APP内.因此咱们使用CSR申请证书时,咱们还要申请一个东西!! 就是描述文件!
在开发时,编译完一个 APP 后,用本地的私钥M对这个APP进行签名,同时把从苹果服务器获得的 Provisioning Profile文件打包进APP里,文件名统一改成embedded.mobileprovision,把 APP 安装到手机上.最后iOS系统进行验证。
终端查看描述文件内容:security cms -Di embedded.mobileprovision
能够看到就是一个plist文件,里面有不少键值对,其中key为entitlements,这个键值对在后面使用codesign重签应用的时候会用到
最终的流程以下图所示: 能够看到iPhone手机在安装APP的时候,先使用iOS系统内置的公钥A去验证APP内部的公钥M(公钥M被苹果服务器的私钥A签名了),验证经过以后的公钥M再去验证当前的APP(当前APP被私钥M签名了),验证经过以后才能够进行安装行为;
了解了iOS应用的签名原理以后,咱们是否是能够作一个大胆猜测,对于任何不是咱们开发的APP,咱们能不能使用咱们的描述文件和证书来从新签名,别人的APP通过咱们重签后就会被Xcode认为是咱们当前正在开发的APP,从而能够附加调试了;实际上,咱们确实能够对任何来源的APP进行重签和附加调试,可是前提是这个APP必须是砸壳过的APP,pp助手iOS版下架后,如今网上砸壳过的APP很差找了,就只有本身动手砸壳了,这个咱们之后会讲,若是有须要的能够私我
codesign 是Xcode自带的签名工具,咱们能够先使用它来帮我完成重签名,后面也能够直接使用Xcode进行重签;
下面先介绍一下相关一些命令:
codesign -vv -d xxx.app
查看xxx.app的一些签名信息
security find-identity -v -p codesigning
查看当前电脑上的证书
otool -l xxx | grep cryptid
查看MachO文件xxx并筛选结果包含cryptid的信息,能够根据cryptid的值肯定当前APP是否加密,1表明加密,0表明未加密
otool -l xxx > ~/Desktop/123.txt
查看MachO文件xxx,并将结果以123.txt保存在桌面
咱们以微信为例子来进行重签名,在拿到已经砸壳过的微信ipa包以后,用归档实用工具解压 咱们只须要Payload里面的.app包
右键.app包显示包内容后,开始下面的步骤
没有权限的二进制文件是白色的 提高权限以后变成黑色的
再将新建Demo的描述文件,复制到WeChat.app内
把WeChat.app里面的info.plist的BundleID改成新建的Demo的BundleID
受权文件在描述文件里面,输入security cms -Di embedded.mobileprovision
能够查看描述文件具体信息 找到里面key为Entilements的这一部分,把红圈起来的部分复制并新建一个新的plist文件保存下来
再把这个plist文件,放到和WeChat.app同目录下,准备重签
打开终端,输入如下命令进行重签:codesign -fs "你的证书" --no-strict --entitlements=ent.plist WeChat.app
可使用
codesign -vv -d WeChat.app
命令查看咱们是否成功重签了,变成你的证书和BundleID就表明成功了 到此,这个WeChat就被咱们重签成功了!!!此时,咱们可使用Xcode将这个WeChat安装到咱们的手机上
若是你的手机上原本有一个官方正版微信,你如今会发现手机上出现了两个微信;接下来你能够打开刚刚新建的WeChatDemo项目,选择Debug->Attach to Process->WeChat,若是有两个WeChat能够把正版的WeChat从后台划掉,或者选择后面数字较大的那个WeChat,你会发现微信就这样被咱们的WeChatDemo项目链接起来了...能够对微信像调试咱们本身APP同样viewDebug了
经过使用codesign手动重签过程后,发现其实上述过程并不难,只是过程特别的复杂和繁琐,Xcode能够帮咱们简化一些复杂繁琐的过程,那么如今咱们直接使用Xcode来重签;
这里须要注意一下,由于老版本微信(这里使用的WeChat版本是7.0.7)是没有SceneDelegate的,因此新工程也要把SceneDelegate干掉,跟没有这个东西以前同样;(删掉SceneDelegate的.h和.m文件;AppDelegate添加window属性并初始化,删除UISceneSession lifecycle相关代码;info.plist文件中删掉Application Scene Manifest字段)
把新建工程的APP包替换成刚刚重签过的APP包
最后在新工程的下command + R或者点击运行按钮,就会发现别人的项目被咱们的Xcode跑起来了
对比下来发现使用Xcode来重签并附加调试别人的APP仍是要简单方便一点
通过上述两种手动重签的以后,咱们知道了重签的原理了,那么咱们能够将上面的手动签名的步骤写成脚本,让Xcode来执行咱们的脚本进行自动重签,脚本我已经准备好了,下面是使用脚本重签的步骤:
这一步仍是跟以前同样,为了把描述文件安装到真机上,可是使用脚原本重签的话就不须要新建一个跟待重签APP同名的工程了
由于脚本须要知道重签的ipa在哪,就规定了一个路径,就是工程根目录下新建一个APP目录,并把ipa包放在里面
脚本放到工程根目录下后,咱们能够按下图所示的配置好脚本,其中${SRCROOT}是Xcode环境变量,表明了项目的根目录,而appSign.sh就是咱们的脚本文件
接下来command + R运行就能够运行并调试他人APP了,有可能报一些权限问题安装不了啥的,那就Command + shift + k清一下缓存再command + R运行,用上脚本以后可真是太舒服了,那为何还要讲之那些手动重签的步骤呢...固然是学习脚本背后的原理啊
github地址:github.com/DanTheMan82… 这是一个Mac上的APP,能够用来给企业开发者帐号重签别人开发的APP来分发的,不过底层的原理也是相似的,只是用途不同