1. 苹果使用证书的目的是什么
2. AppStore安装app时的认证流程
3. 开发者怎么在debug模式下把app安装到设备呢
一、背景
在 iOS 出来之前,在主流操作系统(Mac/Windows/Linux)上开发和运行软件是不需要签名的,软件随便从哪里下载都能运行,导致平台对第三方软件难以控制,盗版流行。苹果希望解决这样的问题,在 iOS 平台对第三方 APP 有绝对的控制权
,一定要保证每一个安装到 iOS 上的 APP
都是经过苹果官方认证
的。
1.对称加密
对称加密
是密码学中一类加密算法的统称,这类算法在加密与解密时使用相同的密钥
,或者使用两个可以简单的相互推算的密钥。常见的对称加密算法有AES、DES、3DES、RC5
等。相比非对称加密算法,对称加密算法的优点是加解密的速度很快
。
2.非对称加密
非对称加密
是指加密密钥与解密密钥是成对出现的,其中一个对外公开,叫公钥
,另一个末公开的叫私钥
,几乎不能从一个密钥计算出另一个密钥。通过私钥加密的只能通过公钥解密,公钥加密的只能通过私钥解密。最著名的非对称加密算法是RSA
算法。当然如此强大可靠的安全性是在牺牲加密速度的基础上得到的。
3.数字签名
通常我们所说的签名就是数字签名
,它是基于非对称加密算法
实现的。这里的非对称加密就是我们所熟知的RSA
,要了解RSA背后的数学原理可以参考RSA算法原理(一)(二)
- 首先用一种算法,算出原始数据的
摘要
。需满足
a.若原始数据有任何变化,计算出来的摘要值都会变化。
b.摘要要够短。这里最常用的算法是MD5
。 - 生成一份
非对称加密
的公钥和私钥,私钥我自己拿着,公钥公布出去。 - 对一份数据,算出
摘要
后,用私钥加密
这个摘要,得到一份加密后的数据,称为原始数据的签名
。把它跟原始数据一起发送给用户。 - 用户收到数据和签名后,用
公钥解密
得到摘要。同时用户用同样的算法计算原始数据的摘要
,对比这里计算出来的摘要和用公钥解密签名得到的摘要是否相等
,若相等则表示这份数据中途没有被篡改过,因为如果篡改过,摘要会变化。
二、从App Store安装APP
苹果官方生成一对公私钥,在iOS
里内置一个公钥
,私钥
由苹果后台
保存,我们传 App 上 AppStore 时,苹果后台用私钥对 APP 数据进行签名
,iOS 系统下载这个 APP 后,用公钥验证这个签名,若签名正确,这个 APP 肯定是由苹果后台认证的,并且没有被修改过,也就达到了苹果的需求:保证安装的每一个 APP 都是经过苹果官方允许的
三、其他方式安装APP
-
Debug
开发App时可以直接把开发中的应用安装进手机调试; -
In-House
企业内部分发,可以直接安装企业证书签名后的App; -
AD-Hoc
相当于企业分发的限制版,限制安装设备数量,较少用。
image.png
1、在Mac
上生成一对公私钥,这里称公钥M,私钥M。
2、苹果
自己有固定
的一对公私钥,跟上面AppStore例子一样,私钥在苹果后台,公钥内置在每个iOS设备上,这里称为公钥A,私钥A。
3、把公钥M上传到苹果后台,用苹果后台里的私钥A去签名公钥M。得到一份数据包含了公钥M以及其签名(也就是公钥的HASH值
),把这份数据称为证书
。
4、在苹果后台申请AppID,配置好设备ID列表和APP可使用的权限,再加上第3步的证书,组成的数据用私钥A签名,把数据和签名一起组成一个Provisioning Profile
文件,下载到本地Mac开发机。
5、 在开发时,编译完一个APP后,用本地的私钥M对这个APP进行签名,同时把第4步得到的Provisioning Profile
文件打包进APP里,文件名为 embedded.mobileprovision
,把APP安装到手机上。
6、在安装时,iOS系统取得证书,通过系统内置的公钥A
,去验证证书
的数字签名
是否正确。
验证证书确保公钥M
是苹果认证过
的,再用公钥M去验证App的签名
,这里就间接验证了这个App的安装行为是否经过苹果官方允许。(这里只验证安装行为,不验证App是否被改动,因为开发阶段App内容总是不断变化的,苹果不需要管)。
上述步骤对应到我们平常具体的操作和概念是这样的:
第1步
对应的是keychain里的“从证书颁发机构请求证书”
,这里就本地生成了一对公私钥,保存的CertificateSigningRequest
就是公钥
,私钥
保存在本地电脑
里。
第2步
苹果自己处理,我们不用管。
第3步
对应把CertificateSigningRequest
传到苹果后台生成证书,并下载到本地。这时本地有两个证书,一个是第1步生成的,一个是这里下载回来的,keychain会把这两个证书关联起来,因为它们的公私钥是对应的,在Xcode选择下载回来的证书的时,实际上会找到keychain里面对应的私钥去签名。这里私钥只有生成它的这台Mac才有,如果别的Mac也要编译签名这个App,把私钥导出给其他Mac使用,在keychain里面导出私钥,就会存成.p12
文件,其他Mac打开后就导入私钥。
第4步
都是在苹果网站上操作,配置AppID、权限、设备等,最后下载 Provisioning Profile文件。
第5步
Xcode会通过第3步下载回来的证书(存着本地公钥),在本地找到对应的私钥(第1步生成的),用本地私钥去签名App,并把Provisioning Profile文件命名为embedded.mobileprovision
一起打包进去。这里对App的签名数据保存分为两部分,Mach-O可执行文件会把签名直接写入这个文件里,其他资源文件则会保存在_CodeSignature目录下。
第6、7步
的打包和验证都是 Xcode 和 iOS 系统自动做的事。
四、总结
证书
:内容是公钥或私钥,由其他机构对其签名组成的数据包。
Entitlements
:包含了App权限开关列表。
CertificateSigningRequest
:本地公钥。
.p12
:本地私钥,可以导入到其他电脑。
Provisioning Profile
:包含了 证书/Entitlements 等数据,并由苹果后台私钥签名的数据包
其他发布方式
前面以开发包为例子说了签名和验证的流程,另外两种方式In-House企业签名和AD-Hoc流程也是差不多的,只是企业签名不限制安装的设备数,另外需要用户在iOS系统设置上手动点击信任这个企业才能通过验证。
而AppStore的签名验证方式有些不一样,前面我们说到最简单的签名方式,苹果在后台直接用私钥签名App就可以了,实际上苹果确实是这样做的,如果去下载一个AppStore的安装包
,会发现它里面是没有embedded.mobileprovision
文件的,也就是它安装和启动的流程是不依赖这个文件,验证流程也就跟上述几种类型不一样了。
因为上传到AppStore的包苹果会重新对内容加密,原来的本地私钥签名就没有用了,需要重新签名,从AppStore下载的包苹果也并不打算控制它的有效期,不需要内置一个embedded.mobileprovision去做校验,直接在苹果用后台的私钥重新签名,iOS安装时用本地公钥验证App签名就可以了。
那为什么发布AppStore的包还是要跟开发版一样搞各种证书和Provisioning Profile,因为苹果想做统一管理
,Provisioning Profile里包含一些权限控制,AppID 的检验等,苹果不想在上传AppStore 包时重新用另一种协议做一遍这些验证,就不如统一把这部分放在 Provisioning Profile里,上传AppStore时只要用同样的流程验证这个 Provisioning Profile是否合法就可以了。
所以 App 上传到AppStore后,就跟你的 证书 / Provisioning Profile 都没有关系了,无论他们是否过期或被废除,都不会影响AppStore 上的安装包。
以上就是整个签名的大致分析。