从真机调试角度理解ios证书机制
非对称加密
理解非对称加密是理解证书机制的关键。非对称加密就是加密密钥和解密密钥是不同的加密方式。典型用法如下:
- 对信息保密:使用接收人的公钥对明文加密,然后传输给接收人。这样密文只能通过接收人的私钥解密,即便传输过程中密文被截获也是无法解开的,这就保证了信息传输的保密性。
- 验证报文所属人身份和防止篡改(签名):使用发送人的私钥对报文进行加密,就是发送人对报文进行了签名。签名后的报文只能通过发送人的公钥来解密,这就保证了报文的真实性,即报文确实为发送人所属。另外如果密文在传输过程中被截获并修改之后再发送过来,密文无法解密,就知道报文在被篡改了,这样就保证报文的完整性。因此签名的作用就是为了保证报文的真实性和完整性。
著名的RSA算法就是非对称加密算法。
数字签名
前面说过通过私钥加密,公钥解密能起到签名的作用。然而往往不是直接对明文原文进行签名。
非对称加密算法有一个缺点就是对很长的明文进行加密比较耗时,因此在实际使用中通常都是先将报文通过摘要算法得到摘要,再对摘要进行加密,然后将明文和加密后的摘要以及公钥一同发送出去。接收人先对摘要密文进行解密,再对明文使用摘要算法得到的摘要和解密后摘要进行比对,如果一致则说明明文没有被篡改过。这就是所谓的数字签名。
对于摘要算法这里不再叙述,典型的摘要算法有MD5和SHA。
数字证书
设想一种情况,A为了欺骗B,可以向B发送一份伪造是C发送的报文。A用自己的私钥对文件加密,连同A的公钥一并发给B,并谎称是公钥是C的。那么B怎么知道公钥到时是不是C的呢?这就轮到数字证书出场了!
首先,证书的存在,必然是为了证明某种事实。四六级证书证明了我的英语水平、驾驶证证明了我有驾驶资格。数字证书的存在,则是为了证明证书持有者的身份,好比一张网络身份证。数字证书的颁发者是CA(证书机构),受证者即为证书的所有者,可以是企业或个人,也可以是网络设备。数字证书即被CA签过名的证书,就好像被权威机构盖过章,这样证书的有效性就能生成了。
之所以说数字证书能证明证书持有者的身份,是因为:证书中包含了证书持有者信息和证书持有者公钥,通过权威机构(CA)的认证,数字证书就有了其有效性,就好比身份证被公安局盖了章之后,就能证明一个人的身份了。
这样一来,A就无法伪造成C了。因为B要核实报文持有者的身份,只要将A发送过来的数字证书拿去CA查询,数字证书中的公钥已经和证书持有人绑定在一起了,一查询即可知道公钥到底是A的还是C的了。这个过程就好像A给B出示了一张身份证,B一看就知道对方到底是A还是C了。
ios证书申请
要想在真机上运行app,首先要做的就是向MC(Member Center)申请开发证书,来证明你是一个开发者。在申请开发者证书之前需要安装苹果开发者根证书,安装这个证书意味着我们的开发工具对此CA的信任,从而可以用此CA签发的其他证书进行签名和打包。该证书随着XCode的安装自动安装在了Key Chain中。
在向MC申请开发证书时,我们会向MC提交一个certSigningRequest文件,全名为CertificateSigningRequest.certSigningRequest。这个文件到底是什么呢?这个文件里主要包含了两部分内容:
- 申请者信息(用申请者的私钥加密过)
- 申请者公钥
MC在拿到certSigningRequest文件后根本不管其中的申请者信息,而是取出其中的公钥,将其和我的开发者账号信息一起封装在证书中,然后进行数字签名。这样一份数字证书就制作好了。
下载制作好的开发者证书,然后安装,此时Kay Chain就会自动将证书中的公钥和本机的私钥关联起来。在Key Chain中可以看到:
制作描述文件
若要真机调试,必须对ios设备添加描述文件mobileprovision。描述文件描述了可由哪台电脑,把哪个App,安装到哪台手机上面。这个文件是一些信息的集合,打包了AppID、用于调试的Device UDID以及开发证书(这里不再介绍这几种信息),同样是被苹果签名的,因此在获取后就不能随意篡改。
真机调试前,确保对应的设备已经安装了该描述文件,然后XCode中选择本机中对应的证书,就能在真机上运行了。实际上是先打包再安装到真机上,而后运行。下面说一下打包过程中的代码签名。
代码签名
ios程序的最终归宿都是.ipa,即被打包成app,一般我们用Xcode自带的archive功能来打包ipa和签名。签名所用的私钥是我们在XCode中选择的证书对应的私钥(因此事实上在电脑上安装证书并没有实际用处,只是使XCode能用通过它来对应到相应的私钥,真正用于签名的是私钥)。并不是对ipa进行签名,而是只签名包里面的部分文件,先来看看ipa包中都有哪些文件:
ipa文件实际上是一个压缩文件,可以直接修改后缀后解压出来。解压查看可以看到里面包含的内容如下:
- 资源文件,例如图片、html、等等。
- _CodeSignature/CodeResources。这是一个plist文件,可用文本查看,其中的内容就是是程序包中(不包括Frameworks)所有文件的签名。注意这里是所有文件。意味着你的程序一旦签名,就不能更改其中任何的东西,包括资源文件和可执行文件本身。iOS系统会检查这些签名。
- 可执行文件。此文件跟资源文件一样需要签名。
- 一个mobileprovision文件.打包的时候使用的,从MC上生成的。
- Frameworks。程序引用的非系统自带的Frameworks,每个Frameworks其实就是一个app,其中的结构应该和app差不多,也包含签名信息CodeResources文件。
- info.plist文件。
其中需要签名的就是可执行文件和资源文件,这一签名过程就叫代码签名,保证打包后的程序不能被修改。可见代码签名是由机器完成的。
ios设备验证app
设备要安装运行app,首先要验证app的合法性。设备解压ipa包,然后取出mobileprovision文件,该文件是有苹果签名的,首先对其进行校验。然后要做的是:
1.检查设备UDID是否存在mobileprovision的设备UDID列表中。
2.取出mobileprovision文件中的AppID,对比info.plist中的BundleId,是否相符。
3.取出mobileprovision文件中的开发证书,首先通过CA公钥验证证书的有效性。然后通过其中的公钥对机器签名过的所有文件进行验证。
验证app合法后方可安装在设备上运行。
总结
- 非对称加密算法是关键
- 数字证书的作用是证明证书持有者的身份!怎么理解?数字证书中含有证书持有者的公钥以及持有者信息,经过CA认证后证书的有效性就生成了,同时将这把公钥和证书持有者绑定在了一起。而所谓验证证书的有效性就是使用CA的公钥验证证书上CA的签名。
- 数字签名的作用是验证报文所属人的身份以及防止篡改。
- app在打包时通过机器中的私钥进行代码签名,配置文件则是用于ios设备验证app是否合法。
参考文档:
《漫谈iOS程序的证书和签名机制》
《不让苹果开发者账号折磨我》