0.前置参考资料
如果你还不是开发者、没申请过开发者证书、没真机build过App,那你可能对下面要讲的东西不知所云~如何加入开发者?请参考iQA 新人第一天
1.iDP账号类型
iDP(iOS Developer Program)共有四种,个人、公司、企业、教育(暂不介绍)
个人:99$/year,一个开发者而已,如果多个人开发,需要把一份证书导给其他人用,限制调试设备为100台
公司:99$/year,申请较麻烦,支持多个开发者,不限制数量,每个人都有自己的开发证书,限制调试设备为100台
企业:299$/year,可内部发布,不需要提交到AppStore,不限制设备数量
我们公司目前共有三个iDP账号:
Sankuai Technology:公司版,主要是面向用户的产品,如美团、外卖、猫眼等,最终会发布到AppStore
Beijing Sankuai Online Technology:公司版,主要用于测试,目前不会发布产品
Beijing Sankuai Technology:企业版,用于发布内部测试产品或员工产品,大部分会提交到抢鲜平台
2.证书类型
每个iDP内都可创建证书,那么证书从类型上也可以分为以下两种:
Development:可以调试,一般用于RD自己真机开发
Distribution:不可调试,如果是个人或公司账号,可通过iTC(iTunes Connect)提交到AppStore或企业内部的分发平台
0.怎么创建证书?
前置资料有介绍
1.证书可以在哪里下载到呢?
用开发者账号登录developer.apple.com,在Member Center->Certificates中可以找到全部证书,根据Type字段我们可以判断这个证书属于那种类型,在这里也可以下载到自己的开发者证书。(这里下载别人的证书是没有意义的哈)
2.下载证书并导入本机后在哪里能查看到呢?
a.打开本机钥匙串访问工具(Keychain Access),如图中部分即是开发者证书。
b.用命令行:
securityfind-identity -v-p codesigning
3.如何进行签名
代码签名目前常用的有两种方式:Xcode和codesign命令行,前者适用于人工,后者适用于自动化。
1.Xcode(TARGETS-Build Settings-Code Signing)
如上图红框位置,可以设置用哪个证书来进行代码签名,此处设置的是iOS Developer,Xcode会自动从本机keychain中寻找适合的开发者证书来签名。
->当然你也许会奇怪为什么不具体指定到个人的证书呢?当我们的工程要多人协作开发,如果这里被你指定为小A的证书,那么在小B的开发环境中,是没有小A证书的!小B还需要在这里指定使用小B的证书!这就出现需要经常修改工程文件的问题。
当工程设置完毕后,我们按command+r来进行真机调试
2.codesign 命令
如果你想自动化做一些事情,总不能依赖于Xcode吧?所以这个时候codesign登场了(其实Xcode也是调用了codesign进行了签名)
codesign -f -s"iPhone Developer: 海亮 梁 (PP5J5U38RP)"--resource-rules xxx.app/ResourceRules.plist xxx.app
命令中的 -s参数跟所用证书名字,要与本机证书名字一一对应(相差一个空格都不对),上边已经介绍了查看本机证书列表的两个方法,所以最好复制粘贴。
4.签名信息
那么对于已经签名的App,我们怎么查看它的签名信息呢?或者怎么确定这个App的来源?
可通过codesign命令查看当前App的签名信息,如下图,这个是用我自己的证书签名的且证书类型属于Development(真机调试用的):
下图的App是用公司的证书签名的且属于Distribution类型(即将要提交到AppStore前)
下图的App是提交到AppStore之后的签名信息
发现了吗?我们的App在AppStore提交前和审核通过后的签名信息变了!为什么这样做呢?这里不做解释,请看下面的授权描述文件。
5.授权描述文件
为什么要有授权描述文件?
因为iOS设备默认只信任苹果签名的App(其他签名的App是安装不到手机上的),但是为了避免开发者真机Debug App、企业分发自己的App等需求,引入了授权描述文件,它的作用是让iOS可以安装运行来自非AppStore的App(比如我们的大象客户端、RD在真机进行调试)
其实根据iDP类型不同,授权描述文件也分两种:普通授权描述文件(对应个人版和公司版)和企业版授权描述文件,不过差别较小。
普通授权描述文件与企业授权描述文件的在作用上有两点:
前者BundleID可用通配符,可以授权任意App,后者需要明确指定
前者最大支持授权100台设备,后者不需要指定设备(即授权任意设备)
1.授权描述文件在哪里下载?
可以看到当前授权描述文件的状态是Managed by Xcode,意思是已经被Xcode自动管理了。
事实上,从Xcode5之后,授权描述文件的概念对于admin来说就模糊了,因为Xcode可以自动管理授权描述文件了!在这以前每有一台新机器加入或新开发者加入,都需要手动Edit授权描述文件,否则新设备/新开发者还是不能真机调试的。
->我们经常遇到一个问题:当RD发现测试手机A上独有的一个Bug,但A尚未加入可调式设备列表,这时让admin将A加入可调式设备列表中了,但是RD这边还是不能真机调试A,原因就是本地授权描述文件尚未更新。那么如何更新授权描述文件?
Xcode->Preferences->Accounts->View Details->点击刷新按钮即可更新!
虽然授权描述文件的更新和下载过程我们是看不到的,但是Xcode总归是要把授权描述文件下载下来的吧,我们可以找到下载结果!
用find命令可以帮助我们哈,查询结果显示,Xcode将授权描述文件保存在了以下这个目录!其实之前流传的“手动下载授权描述文件后双击导入”的方式,就是导入到这个目录
/Users/xxx/Library/MobileDevice/Provisioning Profiles
授权描述文件内部结构
上面说了真机调试不需要手动下载授权描述文件,但是如果我们想要研究授权描述文件,还是需要手动下载下来的。下载之后可以通过文本工具查看,因为就是一个plist格式的文件。
授权描述文件包括了基本描述信息、证书列表、授权设备列表、entitlements,文件本身被Apple签名了
授权描述文件需要随App一起打进IPA里,名字是embedded.mobileprovision,我们可以通过解压IPA来找到App中的这个文件
左图中是公司版iDP生成的授权描述文件,右图是企业版iDP生成的授权描述文件。
从图中可以看到相同点和不同点:
TeamName\ExpirationDate\...:顾名思义。
application-identifier:表示授权的AppID,所以授权描述文件与App是对应的,不要忘记,这里可以出现*(即授权任意BundleID)
DeveloperCertificates:这里的Array包含了开发者证书
ProvisionedDevices:授权设备,这里的Array包含了可授权设备的UDID;公司版和个人版的iDP只能添加100个设备,而企业版这里看到了吗?叫ProvisionsAllDevices=YES,即授权了任意设备!
get-task-allow:表示当前App可否被Debug
补充一点
上面提到了get-task-allow,可以发现对于Development和Distribution两种类型的授权描述文件,前者总是true,后者总是false,这也是正常的~因为发布出去的App肯定是不可以被Debug的对吧
get-task-allow很神奇,除此之外,还有很多未公开的Entitlements,感兴趣的话可以参考外部链接
6.重签名
重签名可以干毛?
苹果在收到iOS开发者提交的App后,如果经过审核则会进行重签名并上架,所以会发现从App Store下载下来的App签名与在iTC上提交的不一样!
目前市面上的各种第三方渠道都会进行重签名发布,如同步推、xy助手等,用的是企业版授权描述文件可以在任意机器上跑
其它用途:自动化竞对App等,参考链接自动化测试竞对APP,自动化测试竞对APP(二)
->有些第三方渠道会号称“免越狱,用正版App”,那么它们是怎么做到的呢?
此图是第三方渠道上下载的App,我们可以看到图中的签名与我们当时提交给该渠道的签名也是不一致的!也就是说第三方渠道也是对App进行了重签名(用企业证书)。
7.签名原理
签名原理会比较复杂,其中会涉及到几个算法或编码格式:
sha1:信息摘要算法(或哈希算法,名字很多),通过sha1可以对任意文件生成唯一哈希值,即可以鉴别文件是否被篡改
RSA:非对称加密算法(或公钥加密,名字也很多),一共两个秘钥,分公钥与私钥,加解密是用不同的秘钥,这里的用途是用RSA对App中每个文件的散列值进行加密
base64:一种编码格式(非加密算法哈~),用途很广,在这里的用途是将RSA加密后的密文进行文本编码,以利于在本文格式的文档中储存
->这里讲起来较复杂,我想起来一个国王与菜农的故事,可以讲清这个原理。
二进制文件签名信息
以上两张图中自己看你会发现,CodeResources里面的签名信息只是包含了资源文件(图片\nib\等等),而最终要的二进制文件不列在其中,这是咋回事?
因为二进制文件的签名是内嵌式的,可以通过以下命令查看
otool -l imeituan|grep"cmd LC_CODE_SIGNATURE"-A 5
根据输出结果,我们可以看到签名信息位于二进制中偏移量为71215792的位置,大小为357984
关于Mach-O格式的介绍,敬请关注我们后续课程~~
7.Free Provisioning
Xcode7现在已经可以支持免费的iDP账号在真机上进行调试,这就意味着将来真机Build App将变得简单~