漫谈iOS程序的证书和签名机制
接触iOS开发半年,曾经也被这个主题坑的摸不着头脑,也在淘宝上买过企业证书签名这些服务,有大神都做了一个全自动的发布打包(不过此大神现在不卖企业证书了),甚是羡慕和崇拜。于是,花了一点时间去研究了一下iOS这套证书和签名机制,并撰文分享给需要的朋友。由于本人才疏学浅,多有遗漏或错误之处,还请大神多多指教。
非对称加密和摘要
非对称加密的特性和用法
非对称加密算法可能是世界上最重要的算法,它是当今电子商务等领域的基石。简而言之,非对称加密就是指加密密钥和解密密钥是不同的,而且加密密钥和解密密钥是成对出现。非对称加密又叫公钥加密,也就是说成对的密钥,其中一个是对外公开的,所有人都可以获得,称为公钥,而与之相对应的称为私钥,只有这对密钥的生成者才能拥有。公私钥具有以下重要特性:
-
对于一个私钥,有且只有一个与之对应的公钥。生成者负责生成私钥和公钥,并保存私钥,公开公钥
-
公钥是公开的,但不可能通过公钥反推出私钥,或者说极难反推,只能穷举,所以只要密钥足够长度,要通过穷举而得到私钥,几乎是不可能的
-
通过私钥加密的密文只能通过公钥解密,公钥加密的密文只有通过私钥解密
由于上述特性,非对称加密具有以下的典型用法:
-
对信息保密,防止中间人攻击:将明文通过接收人的公钥加密,传输给接收人,因为只有接收人拥有对应的私钥,别人不可能拥有或者不可能通过公钥推算出私钥,所以传输过程中无法被中间人截获。只有拥有私钥的接收人才能阅读。此用法通常用于交换
对称密钥
。 -
身份验证和防止篡改:权限狗用自己的私钥加密一段授权明文,并将授权明文和加密后的密文,以及公钥一并发送出来,接收方只需要通过公钥将密文解密后与授权明文对比是否一致,就可以判断明文在中途是否被篡改过。此方法用于
数字签名
。
著名的RSA
算法就是非对称加密算法,RSA
以三个发明人的首字母命名。
非对称加密算法如此强大可靠,却有一个弊端,就是加解密比较耗时。因此,在实际使用中,往往与对称加密和摘要算法结合使用。对称加密很好理解,此处略过1w字。我们再来看一下摘要算法。
摘要算法
另一个神奇的算法就是摘要算法。摘要算法是指,可以将任意长度的文本,通过一个算法,得到一个固定长度的文本。这里文本不一定只是文本,可以是字节数据。所以摘要算法试图将世间万物,变成一个固定长度的东西。摘要算法具有以下重要特性:
-
只要源文本不同,计算得到的结果,必然不同
-
无法从结果反推出源(那是当然的,不然就能量不守恒了)
典型的摘要算法,比如大名鼎鼎的MD5
和SHA
。摘要算法主要用于比对信息源是否一致,因为只要源发生变化,得到的摘要必然不同;而且通常结果要比源短很多,所以称为“摘要”。
数字签名
理解了非对称加密和摘要算法,来看一下数字签名。实际上数字签名就是两者结合。假设,我们有一段授权文本,需要发布,为了防止中途篡改文本内容,保证文本的完整性,以及文本是由指定的权限狗发的。首先,先将文本内容通过摘要算法,得到摘要,再用权限狗的私钥对摘要进行加密得到密文,将源文本、密文、和私钥对应的公钥一并发布即可。那么如何验证呢?
验证方首先查看公钥是否是权限狗的,然后用公钥对密文进行解密得到摘要,将文本用同样的摘要算法得到摘要,两个摘要进行比对,如果相等那么一切正常。这个过程只要有一步出问题就视为无效。
数字签名可以快速验证文本的完整性和合法性,已广泛应用于各个领域。理解了数字签名以后,我们进一步来看什么是数字证书。
数字证书
现实生活的证书
证书顾名思义,就是权限机构的颁发的证明。比如英语6级证书,就是教育部门颁发给通过了6级考核的个人的证明,证明这个人的英语能力。我们来看一下这个证书的组成:
-
被证明人:老王
-
内容:通过了英语六级
-
盖章:教育部门的公章或钢印
于是老王就可以用这张证书找工作了,用人单位会通过查看证书的各项内容(尤其是公章),来验证证书的合法性和老王的能力。
在现实生活中,经常有假的6级证书,这些假证书最重要的就是有一个假公章。现实生活中使用法律法规来约束私刻假公章的行为,但是用人单位可能不能十分准确的判断公章是真是假。而这些问题在数字签名面前都可以用数学的方法严谨的解决。
数字证书:用数字签名实现的证书
实际上,数字证书就是通过数字签名实现的数字化的证书。在一般的证书组成部分中,还加入了其他的信息,比如证书有效期(好比驾驶证初次申领后6年有效),过了有效期,需要重新签发(驾驶证6年有效后需重新申领)。
跟现实生活中的签发机构一样,数字证书的签发机构也有若干,并有不同的用处。比如苹果公司就可以签发跟苹果公司有关的证书,而跟web访问有关的证书则是又几家公认的机构进行签发。这些签发机构称为CA
(Certificate Authority)。
对于被签发人,通常都是企业或开发者。比如需要搭建基于SSL的网站,那么需要从几家国际公认的CA去申请证书;再比如需要开发iOS的应用程序,需要从苹果公司获得相关的证书。这些申请通常是企业或者开发者个人提交给CA的。当然申请所需要的材料、资质和费用都各不相同,是由这些CA制定的,比如苹果要求$99或者$299的费用。
之所以要申请证书,当然是为了被验证。英语6级证书的验证方一般是用人单位;web应用相关的SSL证书的验证方通常是浏览器;iOS各种证书的验证方是iOS设备。我们之所以必须从CA处申请证书,就是因为CA已经将整个验证过程规定好了。对于iOS,iOS系统已经将这个验证过程固化在系统中了,除非越狱,否则无法绕过。
证书的授权链
数字证书可能还包括证书链信息。举个例子:如果你要申请休假1周,需要你的上司审批,你的上司需要他的上司同意,最终需要大老板同意,那么这一层层的授权,形成了一个授权链,大老板是授权链的根(root),中间这些环节分别是被更接近root的人授权的。
我们从苹果MC
(Member Center)中获得的证书实际也是一个包含有证书链的证书,其中的根是苹果的CA。我们获得的证书实际上是在告诉iOS设备:我们的证书是被苹果CA签过名的合法的证书
。而iOS设备在执行app前,首先要先验证CA的签名是否合法,然后再通过证书中我们的公钥验证程序是否的确是我们发布的,且中途没有对程序进行过篡改。
iOS证书申请和签名打包流程图
在继续下去之前,先来看一张图。
这张图阐述了,开发iOS应用程序时,从申请证书,到打包的大致过程。接下来我将对图中的每一个环节进行分析。
证书申请
开发iOS程序,必然要进行的工作就是成为开发者,并申请相关的证书,否则你的程序只能在模拟器上运行,无法在真机上调试,更不要说上架了。那么在申请证书之前需要:
-
支付$99或$299成为苹果开发者,并每年续费。这一步是苹果的强制规定,相当于霸王条款,没钱玩尼玛!大家都知道$99针对个人和小企业,$299针对大企业,这么分没错,不过你需要知道的是,两种金额的本质区别在于你可以获得的证书类型不同,$99当然比$299的少一些。
-
安装苹果开发者根证书,此证书实际上是我们从苹果MC中申请的所有证书的“根证书”,安装这个证书意味着我们的开发工具对此CA的信任,从而可以用此CA签发的其他证书进行签名和打包。一般而言,如果安装了Xcode,那么这个证书是自动安装在Key Chain中了。证书如下图
然后,我们就开始按照很多图文并茂的教程开始申请证书,各种操作。这里由于是讲原理,不展开这部分。我们来看每一步到底意味着什么。
什么是CertificateSigningRequest.certSigningRequest
我们需要生成一个CertificateSigningRequest.certSigningRequest
文件来提交到MC中,从而获取某种证书。那么这个文件到底是什么呢?从上面的流程图中大家可以看到,这个文件包含两部分内容(Certificate signing request):
-
申请者信息,此信息是用申请者的
私钥
加密的 -
申请者公钥,此信息是申请者使用的
私钥
对应的公钥 -
摘要算法和公钥加密算法
我们可以用openssl来解析文件中的内容一窥究竟:
openssl asn1parse -i -in CertificateSigningRequest.certSigningRequest
0:d=0 hl=4 l= 649 cons: SEQUENCE
4:d=1 hl=4 l= 369 cons: SEQUENCE
8:d=2 hl=2 l= 1 prim: INTEGER :00
11:d=2 hl=2 l= 68 cons: SEQUENCE
13:d=3 hl=2 l= 36 cons: SET
15:d=4 hl=2 l= 34 cons: SEQUENCE
17:d=5 hl=2 l= 9 prim: OBJECT :emailAddress
28:d=5 hl=2 l= 21 prim: IA5STRING :zhoupingtkbjb@163.com
51:d=3 hl=2 l= 15 cons: SET
53:d=4 hl=2 l= 13 cons: SEQUENCE
55:d=5 hl=2 l= 3 prim: OBJECT :commonName
60:d=5 hl=2 l= 6 prim: UTF8STRING :Parker
68:d=3 hl=2 l= 11 cons: SET
70:d=4 hl=2 l= 9 cons: SEQUENCE
72:d=5 hl=2 l= 3 prim: OBJECT :countryName
77:d=5 hl=2 l= 2 prim: PRINTABLESTRING :CN
81:d=2 hl=4 l= 290 cons: SEQUENCE
85:d=3 hl=2 l= 13 cons: SEQUENCE
87:d=4 hl=2 l= 9 prim: OBJECT :rsaEncryption
98:d=4 hl=2 l= 0 prim: NULL
100:d=3 hl=4 l= 271 prim: BIT STRING
375:d=2 hl=2 l= 0 cons: cont [ 0 ]
377:d=1 hl=2 l= 13 cons: SEQUENCE
379:d=2 hl=2 l= 9 prim: OBJECT :sha1WithRSAEncryption
390:d=2 hl=2 l= 0 prim: NULL
392:d=1 hl=4 l= 257 prim: BIT STRING
可以看到文件包含了我的信息,并标明使用了sha1
摘要算法和RSA
公钥加密算法。苹果的MC在拿到这个后,将这个信息记录下来,并签发出相关的证书。这里,苹果实际无需验证我的信息,因为如果我不交钱就没办法上传这个文件,也就得不到证书。
从MC中申请到的证书究竟是什么
苹果取出CertificateSigningRequest.certSigningRequest
中的公钥,根本不管我的其他信息,然后将我的MC账号信息
和我提交的公钥封装在证书中,并进行数字签名。以开发证书为例,我们用openssl来看一下证书的内容:
openssl x509 -inform der -in ios_development.cer -noout -text
Certificate:
Data:
Version: 3 (0x2)
Serial Number:
65:97:cd:73:6f:19:37:c2
Signature Algorithm: sha256WithRSAEncryption
Issuer: C=US, O=Apple Inc., OU=Apple Worldwide Developer Relations, CN=Apple Worldwide Developer Relations Certification Authority
Validity
Not Before: Jul 29 07:36:28 2015 GMT
Not After : Jul 28 07:36:28 2016 GMT
Subject: UID=8VPWB57FDW, CN=iPhone Developer: Liang Ding (2U967A2YJ6), OU=7XPNRZE9TC, O=Liang Ding, C=US
Subject Public Key Info:
Public Key Algorithm: rsaEncryption
RSA Public Key: (2048 bit)
Modulus (2048 bit):
00:ab:43:a4:57:32:57:30:81:89:eb:b4:5c:b6:88:
7f:4f:59:3a:9e:f6:14:50:2c:5c:14:6d:01:58:bd:
d7:2b:a6:66:71:f7:d9:da:58:a2:e8:4c:d5:a9:87:
20:5b:b7:4c:58:29:3c:b3:48:de:7f:ad:3f:98:cc:
9d:b3:07:2f:93:4a:3a:e5:32:e2:fc:59:30:1e:ee:
65:11:c3:88:ea:7a:54:d8:60:56:d1:fa:69:06:40:
dd:72:1d:7f:d9:14:85:bf:7a:b0:a3:34:a0:ac:c1:
dc:a9:48:3c:9c:43:c8:e4:fd:02:eb:fe:d2:a7:ce:
2e:e4:9a:51:20:0b:5b:e5:5a:d4:04:9e:a4:52:8d:
c2:1e:1f:50:80:fb:ea:c1:e4:bb:b4:ec:35:fd:96:
6a:86:0a:62:fa:d2:5a:8b:34:1b:f2:c5:c8:c9:2c:
85:d1:4d:8c:cb:91:be:db:92:f0:88:37:7a:6d:8d:
ef:c6:e1:47:5c:e5:ca:e2:5a:47:14:5d:2f:5b:2e:
d4:df:61:d9:99:e2:3e:6b:24:b2:aa:36:b3:af:e6:
a8:a8:28:a7:8a:73:aa:68:a9:71:ac:81:a8:20:98:
bb:3e:76:e2:09:19:41:45:d7:9a:68:1b:7c:1d:f5:
b2:0b:36:ac:f0:4b:fc:0a:f1:3c:de:96:a0:10:14:
aa:79
Exponent: 65537 (0x10001)
X509v3 extensions:
Authority Information Access:
OCSP - URI:http://ocsp.apple.com/ocsp03-wwdr01
X509v3 Subject Key Identifier:
C7:AB:35:54:A3:7B:96:2A:67:55:B8:2F:B6:82:4B:B8:F0:49:0F:EB
X509v3 Basic Constraints: critical
CA:FALSE
X509v3 Authority Key Identifier:
keyid:88:27:17:09:A9:B6:18:60:8B:EC:EB:BA:F6:47:59:C5:52:54:A3:B7
X509v3 Certificate Policies:
Policy: 1.2.840.113635.100.5.1
User Notice:
Explicit Text: Reliance on this certificate by any party assumes acceptance of the then applicable standard terms and conditions of use, certificate policy and certification practice statements.
CPS: http://www.apple.com/certificateauthority/
X509v3 Key Usage: critical
Digital Signature
X509v3 Extended Key Usage: critical
Code Signing
1.2.840.113635.100.6.1.2: critical
..
Signature Algorithm: sha256WithRSAEncryption
80:99:47:27:ae:e5:1e:89:1e:c2:ec:52:d7:c8:8b:df:86:25:
a9:cb:b2:f2:01:6c:5e:a0:55:6c:ad:1d:bd:3b:1c:ce:b4:53:
4d:03:d0:98:f6:f7:0e:24:2b:c5:cb:5e:71:88:bd:53:46:a8:
c7:e0:d9:f4:81:47: